EticaHub

EticaSwap Routercontract Verified

0xaefbf3fB975657a4C71ea0Fb644B4afE5F555723

EGAZ balance
0 EGAZ
ETX balance
0 ETX
ETI balance
0 ETI
EGAZ balance (wrapped ERC-20)
0 EGAZ
Type
Contract
Code size
16297 bytes
Verified

EticaSwapRouter

Compiled with solc 0.8.26+commit.8a97fa7a · optimizer on (1,000,000 runs) · evm paris

bytecode match
match (immutables masked)
Source code · 7 files
src/swap/EticaSwapRouter.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.26;

import {IEticaSwapFactory} from "./interfaces/IEticaSwapFactory.sol";
import {IEticaSwapPair} from "./interfaces/IEticaSwapPair.sol";
import {IERC20Minimal} from "./interfaces/IERC20Minimal.sol";
import {IWEGAZ} from "./interfaces/IWEGAZ.sol";
import {EticaSwapLibrary} from "./libraries/EticaSwapLibrary.sol";
import {TransferHelper} from "./libraries/TransferHelper.sol";

/// @title EticaSwap V2 router
/// @notice User-facing entry point for swap + liquidity ops.
///         Supports ERC20/ERC20 and EGAZ/ERC20 pairs (EGAZ wrapped via WEGAZ).
contract EticaSwapRouter {
    address public immutable factory;
    address public immutable WEGAZ_TOKEN;

    modifier ensure(uint256 deadline) {
        require(deadline >= block.timestamp, "ESwap: EXPIRED");
        _;
    }

    constructor(address _factory, address _wegaz) {
        factory = _factory;
        WEGAZ_TOKEN = _wegaz;
    }

    receive() external payable {
        // Only WEGAZ may send native EGAZ here (on withdraw).
        require(msg.sender == WEGAZ_TOKEN, "ESwap: NOT_WEGAZ");
    }

    // ------------------------------------------------------------------ ADD LIQUIDITY

    function _addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin
    ) internal returns (uint256 amountA, uint256 amountB) {
        IEticaSwapFactory fac = IEticaSwapFactory(factory);
        if (fac.getPair(tokenA, tokenB) == address(0)) {
            // Forward the ETX pair-creation fee from the original caller so
            // `router.addLiquidity` can transparently open a new pair without
            // a separate `factory.createPair` step. Fee is skipped when the
            // router itself is a trusted creator, the fee is zero, or `feeTo`
            // is unset (pre-bootstrap).
            uint256 fee = fac.pairCreationFee();
            address recipient = fac.feeTo();
            if (fee > 0 && recipient != address(0) && !fac.trustedCreators(address(this))) {
                address etxToken = fac.etx();
                TransferHelper.safeTransferFrom(etxToken, msg.sender, address(this), fee);
                TransferHelper.safeApprove(etxToken, factory, fee);
            }
            fac.createPair(tokenA, tokenB);
        }
        (uint256 reserveA, uint256 reserveB) = _reservesOrZero(tokenA, tokenB);
        if (reserveA == 0 && reserveB == 0) {
            (amountA, amountB) = (amountADesired, amountBDesired);
        } else {
            uint256 amountBOptimal = EticaSwapLibrary.quote(amountADesired, reserveA, reserveB);
            if (amountBOptimal <= amountBDesired) {
                require(amountBOptimal >= amountBMin, "ESwap: INSUFFICIENT_B_AMOUNT");
                (amountA, amountB) = (amountADesired, amountBOptimal);
            } else {
                uint256 amountAOptimal = EticaSwapLibrary.quote(amountBDesired, reserveB, reserveA);
                assert(amountAOptimal <= amountADesired);
                require(amountAOptimal >= amountAMin, "ESwap: INSUFFICIENT_A_AMOUNT");
                (amountA, amountB) = (amountAOptimal, amountBDesired);
            }
        }
    }

    function _reservesOrZero(address tokenA, address tokenB)
        private
        view
        returns (uint256 reserveA, uint256 reserveB)
    {
        address pair = IEticaSwapFactory(factory).getPair(tokenA, tokenB);
        if (pair == address(0)) return (0, 0);
        (address token0,) = EticaSwapLibrary.sortTokens(tokenA, tokenB);
        (uint112 r0, uint112 r1,) = IEticaSwapPair(pair).getReserves();
        (reserveA, reserveB) = tokenA == token0 ? (r0, r1) : (r1, r0);
    }

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external ensure(deadline) returns (uint256 amountA, uint256 amountB, uint256 liquidity) {
        (amountA, amountB) =
            _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        address pair = EticaSwapLibrary.pairFor(factory, tokenA, tokenB);
        TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
        TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
        liquidity = IEticaSwapPair(pair).mint(to);
    }

    function addLiquidityEGAZ(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountEGAZMin,
        address to,
        uint256 deadline
    )
        external
        payable
        ensure(deadline)
        returns (uint256 amountToken, uint256 amountEGAZ, uint256 liquidity)
    {
        (amountToken, amountEGAZ) = _addLiquidity(
            token, WEGAZ_TOKEN, amountTokenDesired, msg.value, amountTokenMin, amountEGAZMin
        );
        address pair = EticaSwapLibrary.pairFor(factory, token, WEGAZ_TOKEN);
        TransferHelper.safeTransferFrom(token, msg.sender, pair, amountToken);
        IWEGAZ(WEGAZ_TOKEN).deposit{value: amountEGAZ}();
        assert(IWEGAZ(WEGAZ_TOKEN).transfer(pair, amountEGAZ));
        liquidity = IEticaSwapPair(pair).mint(to);
        if (msg.value > amountEGAZ) {
            TransferHelper.safeTransferEGAZ(msg.sender, msg.value - amountEGAZ);
        }
    }

    // ------------------------------------------------------------------ REMOVE LIQUIDITY

    function removeLiquidity(
        address tokenA,
        address tokenB,
        uint256 liquidity,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) public ensure(deadline) returns (uint256 amountA, uint256 amountB) {
        address pair = EticaSwapLibrary.pairFor(factory, tokenA, tokenB);
        IEticaSwapPair(pair).transferFrom(msg.sender, pair, liquidity);
        (uint256 amount0, uint256 amount1) = IEticaSwapPair(pair).burn(to);
        (address token0,) = EticaSwapLibrary.sortTokens(tokenA, tokenB);
        (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0);
        require(amountA >= amountAMin, "ESwap: INSUFFICIENT_A_AMOUNT");
        require(amountB >= amountBMin, "ESwap: INSUFFICIENT_B_AMOUNT");
    }

    function removeLiquidityEGAZ(
        address token,
        uint256 liquidity,
        uint256 amountTokenMin,
        uint256 amountEGAZMin,
        address to,
        uint256 deadline
    ) public ensure(deadline) returns (uint256 amountToken, uint256 amountEGAZ) {
        (amountToken, amountEGAZ) = removeLiquidity(
            token, WEGAZ_TOKEN, liquidity, amountTokenMin, amountEGAZMin, address(this), deadline
        );
        TransferHelper.safeTransfer(token, to, amountToken);
        IWEGAZ(WEGAZ_TOKEN).withdraw(amountEGAZ);
        TransferHelper.safeTransferEGAZ(to, amountEGAZ);
    }

    // ------------------------------------------------------------------ SWAPS

    function _swap(uint256[] memory amounts, address[] memory path, address _to) internal {
        for (uint256 i; i < path.length - 1; i++) {
            (address input, address output) = (path[i], path[i + 1]);
            (address token0,) = EticaSwapLibrary.sortTokens(input, output);
            uint256 amountOut = amounts[i + 1];
            (uint256 amount0Out, uint256 amount1Out) =
                input == token0 ? (uint256(0), amountOut) : (amountOut, uint256(0));
            address to =
                i < path.length - 2 ? EticaSwapLibrary.pairFor(factory, output, path[i + 2]) : _to;
            IEticaSwapPair(EticaSwapLibrary.pairFor(factory, input, output))
                .swap(amount0Out, amount1Out, to, new bytes(0));
        }
    }

    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external ensure(deadline) returns (uint256[] memory amounts) {
        amounts = EticaSwapLibrary.getAmountsOut(factory, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, "ESwap: INSUFFICIENT_OUTPUT_AMOUNT");
        TransferHelper.safeTransferFrom(
            path[0], msg.sender, EticaSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, to);
    }

    function swapTokensForExactTokens(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external ensure(deadline) returns (uint256[] memory amounts) {
        amounts = EticaSwapLibrary.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= amountInMax, "ESwap: EXCESSIVE_INPUT_AMOUNT");
        TransferHelper.safeTransferFrom(
            path[0], msg.sender, EticaSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, to);
    }

    function swapExactEGAZForTokens(
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable ensure(deadline) returns (uint256[] memory amounts) {
        require(path[0] == WEGAZ_TOKEN, "ESwap: INVALID_PATH");
        amounts = EticaSwapLibrary.getAmountsOut(factory, msg.value, path);
        require(amounts[amounts.length - 1] >= amountOutMin, "ESwap: INSUFFICIENT_OUTPUT_AMOUNT");
        IWEGAZ(WEGAZ_TOKEN).deposit{value: amounts[0]}();
        assert(
            IWEGAZ(WEGAZ_TOKEN)
                .transfer(EticaSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0])
        );
        _swap(amounts, path, to);
    }

    function swapTokensForExactEGAZ(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external ensure(deadline) returns (uint256[] memory amounts) {
        require(path[path.length - 1] == WEGAZ_TOKEN, "ESwap: INVALID_PATH");
        amounts = EticaSwapLibrary.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= amountInMax, "ESwap: EXCESSIVE_INPUT_AMOUNT");
        TransferHelper.safeTransferFrom(
            path[0], msg.sender, EticaSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, address(this));
        IWEGAZ(WEGAZ_TOKEN).withdraw(amounts[amounts.length - 1]);
        TransferHelper.safeTransferEGAZ(to, amounts[amounts.length - 1]);
    }

    function swapExactTokensForEGAZ(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external ensure(deadline) returns (uint256[] memory amounts) {
        require(path[path.length - 1] == WEGAZ_TOKEN, "ESwap: INVALID_PATH");
        amounts = EticaSwapLibrary.getAmountsOut(factory, amountIn, path);
        require(amounts[amounts.length - 1] >= amountOutMin, "ESwap: INSUFFICIENT_OUTPUT_AMOUNT");
        TransferHelper.safeTransferFrom(
            path[0], msg.sender, EticaSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0]
        );
        _swap(amounts, path, address(this));
        IWEGAZ(WEGAZ_TOKEN).withdraw(amounts[amounts.length - 1]);
        TransferHelper.safeTransferEGAZ(to, amounts[amounts.length - 1]);
    }

    function swapEGAZForExactTokens(
        uint256 amountOut,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external payable ensure(deadline) returns (uint256[] memory amounts) {
        require(path[0] == WEGAZ_TOKEN, "ESwap: INVALID_PATH");
        amounts = EticaSwapLibrary.getAmountsIn(factory, amountOut, path);
        require(amounts[0] <= msg.value, "ESwap: EXCESSIVE_INPUT_AMOUNT");
        IWEGAZ(WEGAZ_TOKEN).deposit{value: amounts[0]}();
        assert(
            IWEGAZ(WEGAZ_TOKEN)
                .transfer(EticaSwapLibrary.pairFor(factory, path[0], path[1]), amounts[0])
        );
        _swap(amounts, path, to);
        if (msg.value > amounts[0]) {
            TransferHelper.safeTransferEGAZ(msg.sender, msg.value - amounts[0]);
        }
    }

    // ------------------------------------------------------------------ VIEWS

    function quote(uint256 amountA, uint256 reserveA, uint256 reserveB)
        external
        pure
        returns (uint256)
    {
        return EticaSwapLibrary.quote(amountA, reserveA, reserveB);
    }

    function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut)
        external
        pure
        returns (uint256)
    {
        return EticaSwapLibrary.getAmountOut(amountIn, reserveIn, reserveOut);
    }

    function getAmountIn(uint256 amountOut, uint256 reserveIn, uint256 reserveOut)
        external
        pure
        returns (uint256)
    {
        return EticaSwapLibrary.getAmountIn(amountOut, reserveIn, reserveOut);
    }

    function getAmountsOut(uint256 amountIn, address[] calldata path)
        external
        view
        returns (uint256[] memory)
    {
        return EticaSwapLibrary.getAmountsOut(factory, amountIn, path);
    }

    function getAmountsIn(uint256 amountOut, address[] calldata path)
        external
        view
        returns (uint256[] memory)
    {
        return EticaSwapLibrary.getAmountsIn(factory, amountOut, path);
    }
}
src/swap/interfaces/IERC20Minimal.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

interface IERC20Minimal {
    function balanceOf(address owner) external view returns (uint256);
    function totalSupply() external view returns (uint256);
    function transfer(address to, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
    function approve(address spender, uint256 value) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function decimals() external view returns (uint8);
    function symbol() external view returns (string memory);
    function name() external view returns (string memory);
}
src/swap/interfaces/IEticaSwapFactory.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

/// @title EticaSwap V2 factory interface
/// @notice Uniswap V2–compatible factory deploying CREATE2 pair contracts.
interface IEticaSwapFactory {
    event PairCreated(address indexed token0, address indexed token1, address pair, uint256);
    event TrustedCreatorSet(address indexed creator, bool trusted);
    event PairCreationFeeSet(uint256 fee);

    function etx() external view returns (address);
    function feeTo() external view returns (address);
    function feeToSetter() external view returns (address);
    function trustedCreators(address creator) external view returns (bool);
    function pairCreationFee() external view returns (uint256);

    function getPair(address tokenA, address tokenB) external view returns (address pair);
    function allPairs(uint256) external view returns (address pair);
    function allPairsLength() external view returns (uint256);

    function createPair(address tokenA, address tokenB) external returns (address pair);

    function setFeeTo(address) external;
    function setFeeToSetter(address) external;
    function setTrustedCreator(address creator, bool trusted) external;
    function setPairCreationFee(uint256 fee) external;
}
src/swap/interfaces/IEticaSwapPair.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

/// @title EticaSwap V2 pair interface
/// @notice Uniswap V2–compatible pair (ERC20 LP token + AMM).
interface IEticaSwapPair {
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event Transfer(address indexed from, address indexed to, uint256 value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint256);
    function balanceOf(address owner) external view returns (uint256);
    function allowance(address owner, address spender) external view returns (uint256);

    function approve(address spender, uint256 value) external returns (bool);
    function transfer(address to, uint256 value) external returns (bool);
    function transferFrom(address from, address to, uint256 value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint256);

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    event Mint(address indexed sender, uint256 amount0, uint256 amount1);
    event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint256 amount0In,
        uint256 amount1In,
        uint256 amount0Out,
        uint256 amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint256);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves()
        external
        view
        returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);

    function price0CumulativeLast() external view returns (uint256);
    function price1CumulativeLast() external view returns (uint256);
    function kLast() external view returns (uint256);

    function mint(address to) external returns (uint256 liquidity);
    function burn(address to) external returns (uint256 amount0, uint256 amount1);
    function swap(uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}
src/swap/interfaces/IWEGAZ.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

interface IWEGAZ {
    function deposit() external payable;
    function withdraw(uint256) external;
    function transfer(address to, uint256 value) external returns (bool);
    function balanceOf(address owner) external view returns (uint256);
    function approve(address spender, uint256 value) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}
src/swap/libraries/EticaSwapLibrary.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import {IEticaSwapFactory} from "../interfaces/IEticaSwapFactory.sol";
import {IEticaSwapPair} from "../interfaces/IEticaSwapPair.sol";

/// @notice Pure helpers for the EticaSwap router.
/// @dev Uses `IEticaSwapFactory.getPair` to resolve pair addresses instead of
///      a CREATE2 hardcoded init-code hash, so forks don't have to recompute
///      the hash when bytecode changes.
library EticaSwapLibrary {
    function sortTokens(address tokenA, address tokenB)
        internal
        pure
        returns (address token0, address token1)
    {
        require(tokenA != tokenB, "ESwap: IDENTICAL_ADDRESSES");
        (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
        require(token0 != address(0), "ESwap: ZERO_ADDRESS");
    }

    function pairFor(address factory, address tokenA, address tokenB)
        internal
        view
        returns (address pair)
    {
        pair = IEticaSwapFactory(factory).getPair(tokenA, tokenB);
        require(pair != address(0), "ESwap: PAIR_NOT_FOUND");
    }

    function getReserves(address factory, address tokenA, address tokenB)
        internal
        view
        returns (uint256 reserveA, uint256 reserveB)
    {
        (address token0,) = sortTokens(tokenA, tokenB);
        (uint112 reserve0, uint112 reserve1,) =
            IEticaSwapPair(pairFor(factory, tokenA, tokenB)).getReserves();
        (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
    }

    function quote(uint256 amountA, uint256 reserveA, uint256 reserveB)
        internal
        pure
        returns (uint256 amountB)
    {
        require(amountA > 0, "ESwap: INSUFFICIENT_AMOUNT");
        require(reserveA > 0 && reserveB > 0, "ESwap: INSUFFICIENT_LIQUIDITY");
        amountB = (amountA * reserveB) / reserveA;
    }

    /// @dev 0.30% fee applied to input.
    function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut)
        internal
        pure
        returns (uint256 amountOut)
    {
        require(amountIn > 0, "ESwap: INSUFFICIENT_INPUT_AMOUNT");
        require(reserveIn > 0 && reserveOut > 0, "ESwap: INSUFFICIENT_LIQUIDITY");
        uint256 amountInWithFee = amountIn * 997;
        uint256 numerator = amountInWithFee * reserveOut;
        uint256 denominator = reserveIn * 1000 + amountInWithFee;
        amountOut = numerator / denominator;
    }

    function getAmountIn(uint256 amountOut, uint256 reserveIn, uint256 reserveOut)
        internal
        pure
        returns (uint256 amountIn)
    {
        require(amountOut > 0, "ESwap: INSUFFICIENT_OUTPUT_AMOUNT");
        require(reserveIn > 0 && reserveOut > 0, "ESwap: INSUFFICIENT_LIQUIDITY");
        uint256 numerator = reserveIn * amountOut * 1000;
        uint256 denominator = (reserveOut - amountOut) * 997;
        amountIn = (numerator / denominator) + 1;
    }

    function getAmountsOut(address factory, uint256 amountIn, address[] memory path)
        internal
        view
        returns (uint256[] memory amounts)
    {
        require(path.length >= 2, "ESwap: INVALID_PATH");
        amounts = new uint256[](path.length);
        amounts[0] = amountIn;
        for (uint256 i; i < path.length - 1; i++) {
            (uint256 reserveIn, uint256 reserveOut) = getReserves(factory, path[i], path[i + 1]);
            amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
        }
    }

    function getAmountsIn(address factory, uint256 amountOut, address[] memory path)
        internal
        view
        returns (uint256[] memory amounts)
    {
        require(path.length >= 2, "ESwap: INVALID_PATH");
        amounts = new uint256[](path.length);
        amounts[amounts.length - 1] = amountOut;
        for (uint256 i = path.length - 1; i > 0; i--) {
            (uint256 reserveIn, uint256 reserveOut) = getReserves(factory, path[i - 1], path[i]);
            amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
        }
    }
}
src/swap/libraries/TransferHelper.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

/// @notice Safe transfer helpers that tolerate ERC20s that don't return a boolean.
library TransferHelper {
    function safeApprove(address token, address to, uint256 value) internal {
        (bool ok, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
        require(ok && (data.length == 0 || abi.decode(data, (bool))), "TH: APPROVE_FAILED");
    }

    function safeTransfer(address token, address to, uint256 value) internal {
        (bool ok, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(ok && (data.length == 0 || abi.decode(data, (bool))), "TH: TRANSFER_FAILED");
    }

    function safeTransferFrom(address token, address from, address to, uint256 value) internal {
        (bool ok, bytes memory data) =
            token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
        require(ok && (data.length == 0 || abi.decode(data, (bool))), "TH: TRANSFER_FROM_FAILED");
    }

    function safeTransferEGAZ(address to, uint256 value) internal {
        (bool ok,) = to.call{value: value}(new bytes(0));
        require(ok, "TH: EGAZ_TRANSFER_FAILED");
    }
}
Contract ABI · 19 entries
[
  {
    "type": "constructor",
    "inputs": [
      {
        "name": "_factory",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "_wegaz",
        "type": "address",
        "internalType": "address"
      }
    ],
    "stateMutability": "nonpayable"
  },
  {
    "type": "receive",
    "stateMutability": "payable"
  },
  {
    "type": "function",
    "name": "WEGAZ_TOKEN",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "address",
        "internalType": "address"
      }
    ],
    "stateMutability": "view"
  },
  {
    "type": "function",
    "name": "addLiquidity",
    "inputs": [
      {
        "name": "tokenA",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "tokenB",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "amountADesired",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountBDesired",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountAMin",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountBMin",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "to",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "deadline",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "amountA",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountB",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "liquidity",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "nonpayable"
  },
  {
    "type": "function",
    "name": "addLiquidityEGAZ",
    "inputs": [
      {
        "name": "token",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "amountTokenDesired",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountTokenMin",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountEGAZMin",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "to",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "deadline",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "amountToken",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountEGAZ",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "liquidity",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "payable"
  },
  {
    "type": "function",
    "name": "factory",
    "inputs": [],
    "outputs": [
      {
        "name": "",
        "type": "address",
        "internalType": "address"
      }
    ],
    "stateMutability": "view"
  },
  {
    "type": "function",
    "name": "getAmountIn",
    "inputs": [
      {
        "name": "amountOut",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "reserveIn",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "reserveOut",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "pure"
  },
  {
    "type": "function",
    "name": "getAmountOut",
    "inputs": [
      {
        "name": "amountIn",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "reserveIn",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "reserveOut",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "pure"
  },
  {
    "type": "function",
    "name": "getAmountsIn",
    "inputs": [
      {
        "name": "amountOut",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "path",
        "type": "address[]",
        "internalType": "address[]"
      }
    ],
    "outputs": [
      {
        "name": "",
        "type": "uint256[]",
        "internalType": "uint256[]"
      }
    ],
    "stateMutability": "view"
  },
  {
    "type": "function",
    "name": "getAmountsOut",
    "inputs": [
      {
        "name": "amountIn",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "path",
        "type": "address[]",
        "internalType": "address[]"
      }
    ],
    "outputs": [
      {
        "name": "",
        "type": "uint256[]",
        "internalType": "uint256[]"
      }
    ],
    "stateMutability": "view"
  },
  {
    "type": "function",
    "name": "quote",
    "inputs": [
      {
        "name": "amountA",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "reserveA",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "reserveB",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "pure"
  },
  {
    "type": "function",
    "name": "removeLiquidity",
    "inputs": [
      {
        "name": "tokenA",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "tokenB",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "liquidity",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountAMin",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountBMin",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "to",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "deadline",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "amountA",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountB",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "nonpayable"
  },
  {
    "type": "function",
    "name": "removeLiquidityEGAZ",
    "inputs": [
      {
        "name": "token",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "liquidity",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountTokenMin",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountEGAZMin",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "to",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "deadline",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "amountToken",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountEGAZ",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "stateMutability": "nonpayable"
  },
  {
    "type": "function",
    "name": "swapEGAZForExactTokens",
    "inputs": [
      {
        "name": "amountOut",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "path",
        "type": "address[]",
        "internalType": "address[]"
      },
      {
        "name": "to",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "deadline",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "amounts",
        "type": "uint256[]",
        "internalType": "uint256[]"
      }
    ],
    "stateMutability": "payable"
  },
  {
    "type": "function",
    "name": "swapExactEGAZForTokens",
    "inputs": [
      {
        "name": "amountOutMin",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "path",
        "type": "address[]",
        "internalType": "address[]"
      },
      {
        "name": "to",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "deadline",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "amounts",
        "type": "uint256[]",
        "internalType": "uint256[]"
      }
    ],
    "stateMutability": "payable"
  },
  {
    "type": "function",
    "name": "swapExactTokensForEGAZ",
    "inputs": [
      {
        "name": "amountIn",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountOutMin",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "path",
        "type": "address[]",
        "internalType": "address[]"
      },
      {
        "name": "to",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "deadline",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "amounts",
        "type": "uint256[]",
        "internalType": "uint256[]"
      }
    ],
    "stateMutability": "nonpayable"
  },
  {
    "type": "function",
    "name": "swapExactTokensForTokens",
    "inputs": [
      {
        "name": "amountIn",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountOutMin",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "path",
        "type": "address[]",
        "internalType": "address[]"
      },
      {
        "name": "to",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "deadline",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "amounts",
        "type": "uint256[]",
        "internalType": "uint256[]"
      }
    ],
    "stateMutability": "nonpayable"
  },
  {
    "type": "function",
    "name": "swapTokensForExactEGAZ",
    "inputs": [
      {
        "name": "amountOut",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountInMax",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "path",
        "type": "address[]",
        "internalType": "address[]"
      },
      {
        "name": "to",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "deadline",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "amounts",
        "type": "uint256[]",
        "internalType": "uint256[]"
      }
    ],
    "stateMutability": "nonpayable"
  },
  {
    "type": "function",
    "name": "swapTokensForExactTokens",
    "inputs": [
      {
        "name": "amountOut",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "amountInMax",
        "type": "uint256",
        "internalType": "uint256"
      },
      {
        "name": "path",
        "type": "address[]",
        "internalType": "address[]"
      },
      {
        "name": "to",
        "type": "address",
        "internalType": "address"
      },
      {
        "name": "deadline",
        "type": "uint256",
        "internalType": "uint256"
      }
    ],
    "outputs": [
      {
        "name": "amounts",
        "type": "uint256[]",
        "internalType": "uint256[]"
      }
    ],
    "stateMutability": "nonpayable"
  }
]

Verified 2026-04-22 against on-chain runtime bytecode. Cross-verify manifest on GitHub ↗

Contract

  • WEGAZ_TOKEN()

    No arguments.

    → address
  • factory()

    No arguments.

    → address
  • getAmountIn(uint256, uint256, uint256)
    → uint256
  • getAmountOut(uint256, uint256, uint256)
    → uint256
  • getAmountsIn(uint256, address[])
    → uint256[]
  • getAmountsOut(uint256, address[])
    → uint256[]
  • quote(uint256, uint256, uint256)
    → uint256

Calls go directly to the configured RPC (Etica Mainnet). Writes require a connected wallet on Etica Mainnet (chain ID 61803).

Recent transactions

last 200 blocks

No transactions involving this address in the last 200 blocks. Older activity lives in the public tx-log indexer and can be pulled from the on-chain archive.

Token transfers

recent

No ERC-20 Transfer events involving this address in the indexed window.