Source Code
Overview
S Balance
More Info
ContractCreator
Latest 12 internal transactions
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
17152403 | 12 days ago | 0 S | ||||
17152403 | 12 days ago | 0 S | ||||
17152403 | 12 days ago | 0 S | ||||
17152403 | 12 days ago | 0 S | ||||
17152403 | 12 days ago | 0 S | ||||
17152403 | 12 days ago | 0 S | ||||
17151510 | 12 days ago | 0 S | ||||
17151510 | 12 days ago | 0 S | ||||
17151510 | 12 days ago | 0 S | ||||
17151510 | 12 days ago | 0 S | ||||
17151510 | 12 days ago | 0 S | ||||
17151510 | 12 days ago | 0 S |
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x4CDAfac5...6C7256Be0 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
SlsV1Router
Compiler Version
v0.8.26+commit.8a97fa7a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; import "./interfaces/ISlsV1Factory.sol"; import "./interfaces/ISlsV1Pair.sol"; import "./libraries/SlsV1Library.sol"; import "./interfaces/ISLSErrors.sol"; interface IERC20 { function balanceOf(address) external returns (uint256); function transfer(address to, uint256 amount) external; } contract SlsV1Router is IErrors { error ExcessiveInputAmount(); error InsufficientAAmount(); error InsufficientBAmount(); error InsufficientOutputAmount(); error SafeTransferFailed(); ISlsV1Factory factory; modifier ensure(uint deadline) { require( deadline >= block.timestamp, Sls_Router_Error(SlsError.EXPIRED) ); _; } constructor(address _factory) { factory = ISlsV1Factory(_factory); } function addLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin, address to, uint deadline ) external ensure(deadline) returns (uint256 amountA, uint256 amountB, uint256 liquidity) { if (factory.pairs(tokenA, tokenB) == address(0)) { factory.createPair(tokenA, tokenB); } (amountA, amountB) = _calculateLiquidity( tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin ); address pairAddress = SlsV1Library.pairFor( address(factory), tokenA, tokenB ); _safeTransferFrom(tokenA, msg.sender, pairAddress, amountA); _safeTransferFrom(tokenB, msg.sender, pairAddress, amountB); liquidity = ISlsV1Pair(pairAddress).mint(to); } function removeLiquidity( address tokenA, address tokenB, uint256 liquidity, uint256 amountAMin, uint256 amountBMin, address to, uint deadline ) public ensure(deadline) returns (uint256 amountA, uint256 amountB) { address pair = SlsV1Library.pairFor(address(factory), tokenA, tokenB); ISlsV1Pair(pair).transferFrom(msg.sender, pair, liquidity); (uint amount0, uint amount1) = ISlsV1Pair(pair).burn(to); (address token0, ) = SlsV1Library.sortTokens(tokenA, tokenB); (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0); require( amountA >= amountAMin, Sls_Router_Error(SlsError.INSUFFICIENT_A_AMOUNT) ); require( amountB >= amountBMin, Sls_Router_Error(SlsError.INSUFFICIENT_B_AMOUNT) ); } function swapExactTokensForTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint deadline ) external ensure(deadline) returns (uint256[] memory amounts) { amounts = SlsV1Library.getAmountsOut(address(factory), amountIn, path); require( amounts[amounts.length - 1] >= amountOutMin, Sls_Router_Error(SlsError.INSUFFICIENT_OUTPUT_AMOUNT) ); _safeTransferFrom( path[0], msg.sender, SlsV1Library.pairFor(address(factory), path[0], path[1]), amounts[0] ); _swap(amounts, path, to); } function swapTokensForExactTokens( uint256 amountOut, uint256 amountInMax, address[] calldata path, address to, uint deadline ) external ensure(deadline) returns (uint256[] memory amounts) { amounts = SlsV1Library.getAmountsIn(address(factory), amountOut, path); require( amounts[amounts.length - 1] <= amountInMax, Sls_Router_Error(SlsError.EXCESSIVE_INPUT_AMOUNT) ); _safeTransferFrom( path[0], msg.sender, SlsV1Library.pairFor(address(factory), path[0], path[1]), amounts[0] ); _swap(amounts, path, to); } function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external ensure(deadline) { _safeTransferFrom( path[0], msg.sender, SlsV1Library.pairFor(address(factory), path[0], path[1]), amountIn ); uint balanceBefore = IERC20(path[path.length - 1]).balanceOf(to); _swapSupportingFeeOnTransferTokens(path, to); require( IERC20(path[path.length - 1]).balanceOf(to) - (balanceBefore) >= amountOutMin, "UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT" ); } function _swapSupportingFeeOnTransferTokens( address[] memory path, address _to ) internal virtual { for (uint256 i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); (address token0, ) = SlsV1Library.sortTokens(input, output); ISlsV1Pair pair = ISlsV1Pair( SlsV1Library.pairFor(address(factory), input, output) ); uint256 amountInput; uint256 amountOutput; { // scope to avoid stack too deep errors (uint256 reserve0, uint256 reserve1, ) = pair.getReserves(); (uint256 reserveInput, uint256 reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); amountInput = IERC20(input).balanceOf(address(pair)) - (reserveInput); // amountInput = IERC20(input).balanceOf(address(pair)) - (reserveInput); amountOutput = SlsV1Library.getAmountOut( amountInput, reserveInput, reserveOutput ); } (uint256 amount0Out, uint256 amount1Out) = input == token0 ? (uint256(0), amountOutput) : (amountOutput, uint256(0)); address to = i < path.length - 2 ? SlsV1Library.pairFor(address(factory), output, path[i + 2]) : _to; pair.swap(amount0Out, amount1Out, to); } } // // // // PRIVATE // // // 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, ) = SlsV1Library.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 ? SlsV1Library.pairFor(address(factory), output, path[i + 2]) : to_; ISlsV1Pair(SlsV1Library.pairFor(address(factory), input, output)) .swap(amount0Out, amount1Out, to); } } function _calculateLiquidity( address tokenA, address tokenB, uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, uint256 amountBMin ) internal view returns (uint256 amountA, uint256 amountB) { (uint256 reserveA, uint256 reserveB) = SlsV1Library.getReserves( address(factory), tokenA, tokenB ); if (reserveA == 0 && reserveB == 0) { (amountA, amountB) = (amountADesired, amountBDesired); } else { uint256 amountBOptimal = SlsV1Library.quote( amountADesired, reserveA, reserveB ); if (amountBOptimal <= amountBDesired) { require( amountBOptimal >= amountBMin, Sls_Router_Error(SlsError.INSUFFICIENT_B_AMOUNT) ); (amountA, amountB) = (amountADesired, amountBOptimal); } else { uint256 amountAOptimal = SlsV1Library.quote( amountBDesired, reserveB, reserveA ); assert(amountAOptimal <= amountADesired); require( amountAOptimal >= amountAMin, Sls_Router_Error(SlsError.INSUFFICIENT_A_AMOUNT) ); (amountA, amountB) = (amountAOptimal, amountBDesired); } } } function _safeTransferFrom( address token, address from, address to, uint256 value ) private { (bool success, bytes memory data) = token.call( abi.encodeWithSignature( "transferFrom(address,address,uint256)", from, to, value ) ); require( success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: SAFE_TRANSFER_FROM_FAILED" ); } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; interface ISlsV1Factory { function pairs(address, address) external pure returns (address); function createPair(address, address) external returns (address); function getPair( address tokenA, address tokenB ) external view returns (address pair); function setFeeTo(address) external; function feePool() external view returns (address); }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; interface ISlsV1Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint 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 (uint); function balanceOf(address owner) external view returns (uint); function allowance( address owner, address spender ) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom( address from, address to, uint 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 (uint); function permit( address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s ) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn( address indexed sender, uint amount0, uint amount1, address indexed to ); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); 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 (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; import "../interfaces/ISlsV1Factory.sol"; import "../interfaces/ISlsV1Pair.sol"; import {SlsV1Pair} from "../SlsV1Pair.sol"; import "../interfaces/ISLSErrors.sol"; library SlsV1Library { error InsufficientAmount(); error InsufficientLiquidity(); error InvalidPath(); function getReserves( address factoryAddress, address tokenA, address tokenB ) internal view returns (uint256 reserveA, uint256 reserveB) { (address token0, address token1) = sortTokens(tokenA, tokenB); (uint256 reserve0, uint256 reserve1, ) = ISlsV1Pair( pairFor(factoryAddress, token0, token1) ).getReserves(); (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); } function quote( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) internal pure returns (uint256 amountOut) { require( amountIn > 0, IErrors.Sls_Library_Error(IErrors.SlsError.INSUFFICIENT_A_AMOUNT) ); require( reserveIn > 0 && reserveOut > 0, IErrors.Sls_Library_Error(IErrors.SlsError.INSUFFICIENT_LIQUIDITY) ); return (amountIn * reserveOut) / reserveIn; } function sortTokens( address tokenA, address tokenB ) internal pure returns (address token0, address token1) { return tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); } function pairFor( address factoryAddress, address tokenA, address tokenB ) internal pure returns (address pairAddress) { (address token0, address token1) = sortTokens(tokenA, tokenB); pairAddress = address( uint160( uint256( keccak256( abi.encodePacked( hex"ff", factoryAddress, keccak256(abi.encodePacked(token0, token1)), keccak256(type(SlsV1Pair).creationCode) ) ) ) ) ); } function getAmountOut( uint256 amountIn, uint256 reserveIn, uint256 reserveOut ) internal pure returns (uint256 amountOut) { require( amountIn > 0, IErrors.Sls_Library_Error( IErrors.SlsError.INSUFFICIENT_INPUT_AMOUNT ) ); require( reserveIn > 0 && reserveOut > 0, IErrors.Sls_Library_Error(IErrors.SlsError.INSUFFICIENT_LIQUIDITY) ); uint256 amountInWithFee = amountIn * 997; uint256 numerator = amountInWithFee * reserveOut; uint256 denominator = (reserveIn * 1000) + amountInWithFee; amountOut = numerator / denominator; require( amountOut > 0, IErrors.Sls_Library_Error( IErrors.SlsError.INSUFFICIENT_OUTPUT_AMOUNT ) ); } function getAmountsOut( address factory, uint256 amountIn, address[] memory path ) internal view returns (uint256[] memory) { require( path.length >= 2, IErrors.Sls_Library_Error(IErrors.SlsError.INVALID_PATH) ); uint256[] memory amounts = new uint256[](path.length); amounts[0] = amountIn; for (uint256 i; i < path.length - 1; i++) { (uint256 reserve0, uint256 reserve1) = getReserves( factory, path[i], path[i + 1] ); amounts[i + 1] = getAmountOut(amounts[i], reserve0, reserve1); } return amounts; } function getAmountIn( uint256 amountOut, uint256 reserveIn, uint256 reserveOut ) internal pure returns (uint256) { require( amountOut > 0, IErrors.Sls_Library_Error( IErrors.SlsError.INSUFFICIENT_OUTPUT_AMOUNT ) ); require( reserveIn > 0 && reserveOut > 0, IErrors.Sls_Library_Error(IErrors.SlsError.INSUFFICIENT_LIQUIDITY) ); uint256 numerator = reserveIn * amountOut * 1000; uint256 denominator = (reserveOut - amountOut) * 997; return (numerator / denominator) + 1; } function getAmountsIn( address factory, uint256 amountOut, address[] memory path ) internal view returns (uint256[] memory) { require( path.length >= 2, IErrors.Sls_Library_Error(IErrors.SlsError.INVALID_PATH) ); uint256[] memory amounts = new uint256[](path.length); amounts[amounts.length - 1] = amountOut; for (uint256 i = path.length - 1; i > 0; i--) { (uint256 reserve0, uint256 reserve1) = getReserves( factory, path[i - 1], path[i] ); amounts[i - 1] = getAmountIn(amounts[i], reserve0, reserve1); } return amounts; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IErrors { enum SlsError { NO_ERROR, // 0 UNAUTHORIZED, // 1 IDENTICAL_ADDRESSES, // 2 ZERO_ADDRESS, // 3 BAD_INPUT, //4 PAIR_EXISTS, // 5 LOCKED, // 6 FORBIDDEN, // 7 TRANSFER_FAILED, // 8 EXPIRED, // 9 INSUFFICIENT_LIQUIDITY, // 10 INSUFFICIENT_INPUT_AMOUNT, // 11 INSUFFICIENT_OUTPUT_AMOUNT, // 12 INSUFFICIENT_A_AMOUNT, // 13 INSUFFICIENT_B_AMOUNT, //14 INVALID_PATH, // 15 INSUFFICIENT_LIQUIDITY_MINTED, // 16 OVERFLOW, // 17 INSUFFICIENT_LIQUIDITY_BURNED, // 18 INVALID_TO, // 19 K_ERROR, // 20 EXCESSIVE_INPUT_AMOUNT, // 21 ALREADY_INITIALIZED // 22 } error Sls_Error(SlsError errorID); error Sls_Router_Error(SlsError errorID); error Sls_Library_Error(SlsError errorID); }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; import "solmate/tokens/ERC20.sol"; import "./libraries/Math.sol"; import "./libraries/UQ112x112.sol"; import "./interfaces/ISLSErrors.sol"; import "./interfaces/ISlsV1Factory.sol"; interface IERC20 { function balanceOf(address) external returns (uint256); function transfer(address to, uint256 amount) external; } error AlreadyInitialized(); contract SlsV1Pair is ERC20, IErrors, Math { using UQ112x112 for uint224; uint256 constant MINIMUM_LIQUIDITY = 1000; address public factory; address public token0; address public token1; uint112 private reserve0; uint112 private reserve1; uint32 private blockTimestampLast; uint256 public price0CumulativeLast; uint256 public price1CumulativeLast; uint public kLast; bool private isEntered; event Burn( address indexed sender, uint256 amount0, uint256 amount1, address to ); event Mint(address indexed sender, uint256 amount0, uint256 amount1); event Sync(uint256 reserve0, uint256 reserve1); event Swap( address indexed sender, uint256 amount0Out, uint256 amount1Out, address indexed to ); modifier nonReentrant() { require(!isEntered, Sls_Error(SlsError.LOCKED)); isEntered = true; _; isEntered = false; } constructor() ERC20("SLS V1", "SLS-V1", 18) { // factory = msg.sender; } function initialize(address token0_, address token1_) public { require( token0 == address(0) && token1 == address(0), Sls_Error(SlsError.ALREADY_INITIALIZED) ); // require(msg.sender == factory, Sls_Error(SlsError.FORBIDDEN)); token0 = token0_; token1 = token1_; } function mint( address to ) external nonReentrant returns (uint256 liquidity) { (uint112 reserve0_, uint112 reserve1_, ) = getReserves(); uint256 balance0 = IERC20(token0).balanceOf(address(this)); uint256 balance1 = IERC20(token1).balanceOf(address(this)); uint256 amount0 = balance0 - reserve0_; uint256 amount1 = balance1 - reserve1_; bool feeOn = _mintFee(reserve0_, reserve1_); uint256 _totalSupply = totalSupply; if (_totalSupply == 0) { liquidity = Math.sqrt(amount0 * amount1) - MINIMUM_LIQUIDITY; _mint(address(0), MINIMUM_LIQUIDITY); } else { liquidity = Math.min( (amount0 * _totalSupply) / reserve0_, (amount1 * _totalSupply) / reserve1_ ); } require( liquidity > 0, Sls_Error(SlsError.INSUFFICIENT_LIQUIDITY_MINTED) ); _mint(to, liquidity); _update(balance0, balance1, reserve0_, reserve1_); if (feeOn) { kLast = uint256(reserve0_) * uint256(reserve1_); } emit Mint(to, amount0, amount1); } function _mintFee( uint112 _reserve0, uint112 _reserve1 ) private returns (bool feeOn) { address feeTo = ISlsV1Factory(factory).feePool(); // address feeTo = address(0); feeOn = feeTo != address(0); uint256 _kLast = kLast; if (feeOn) { if (_kLast != 0) { uint256 rootK = Math.sqrt( uint256(_reserve0) * uint256(_reserve1) ); uint256 rootKLast = Math.sqrt(_kLast); if (rootK > rootKLast) { uint256 numerator = totalSupply * (rootK - rootKLast); uint256 denominator = (rootK * 5) + rootKLast; // 0.3% fee >> 1000 - 997 = 3 (based on bps) uint256 feeLiquidity = numerator / denominator; if (feeLiquidity > 0) { _mint(feeTo, feeLiquidity); } } } } else if (_kLast != 0) { kLast = 0; } } function burn( address to ) external nonReentrant returns (uint256 amount0, uint256 amount1) { (uint112 reserve0_, uint112 reserve1_, ) = getReserves(); uint256 balance0 = IERC20(token0).balanceOf(address(this)); uint256 balance1 = IERC20(token1).balanceOf(address(this)); uint256 liquidity = balanceOf[address(this)]; bool feeOn = _mintFee(reserve0_, reserve1_); uint _totalSupply = totalSupply; amount0 = (liquidity * balance0) / _totalSupply; amount1 = (liquidity * balance1) / _totalSupply; require( amount0 > 0 && amount1 > 0, Sls_Error(SlsError.INSUFFICIENT_LIQUIDITY_BURNED) ); _burn(address(this), liquidity); _safeTransfer(token0, to, amount0); _safeTransfer(token1, to, amount1); balance0 = IERC20(token0).balanceOf(address(this)); balance1 = IERC20(token1).balanceOf(address(this)); _update(balance0, balance1, reserve0_, reserve1_); if (feeOn) { kLast = uint(reserve0_) * uint(reserve1_); } emit Burn(msg.sender, amount0, amount1, to); } function swap( uint256 amount0Out, uint256 amount1Out, address to ) external nonReentrant { require( amount0Out > 0 || amount1Out > 0, Sls_Error(SlsError.INSUFFICIENT_OUTPUT_AMOUNT) ); (uint112 reserve0_, uint112 reserve1_, ) = getReserves(); require( amount0Out < reserve0_ && amount1Out < reserve1_, Sls_Error(SlsError.INSUFFICIENT_LIQUIDITY) ); if (amount0Out > 0) _safeTransfer(token0, to, amount0Out); if (amount1Out > 0) _safeTransfer(token1, to, amount1Out); uint256 balance0 = IERC20(token0).balanceOf(address(this)); uint256 balance1 = IERC20(token1).balanceOf(address(this)); uint256 amount0In = balance0 > reserve0 - amount0Out ? balance0 - (reserve0 - amount0Out) : 0; uint256 amount1In = balance1 > reserve1 - amount1Out ? balance1 - (reserve1 - amount1Out) : 0; require( amount0In > 0 || amount1In > 0, Sls_Error(SlsError.INSUFFICIENT_INPUT_AMOUNT) ); // Adjusted = balance before swap - swap fee; fee stays in the contract uint256 balance0Adjusted = (balance0 * 1000) - (amount0In * 3); uint256 balance1Adjusted = (balance1 * 1000) - (amount1In * 3); require( (balance0Adjusted * balance1Adjusted) >= uint256(reserve0_) * uint256(reserve1_) * (1000 ** 2), Sls_Error(SlsError.K_ERROR) ); _update(balance0, balance1, reserve0_, reserve1_); emit Swap(msg.sender, amount0Out, amount1Out, to); } function sync() external nonReentrant { (uint112 reserve0_, uint112 reserve1_, ) = getReserves(); _update( IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0_, reserve1_ ); } function skim(address to) external nonReentrant { address _token0 = token0; // gas savings address _token1 = token1; // gas savings _safeTransfer( _token0, to, IERC20(_token0).balanceOf(address(this)) - (reserve0) ); _safeTransfer( _token1, to, IERC20(_token1).balanceOf(address(this)) - (reserve1) ); } function getReserves() public view returns (uint112, uint112, uint32) { return (reserve0, reserve1, blockTimestampLast); } // // // // PRIVATE // // // function _update( uint256 balance0, uint256 balance1, uint112 reserve0_, uint112 reserve1_ ) private { require( balance0 <= type(uint112).max && balance1 <= type(uint112).max, Sls_Error(SlsError.OVERFLOW) ); unchecked { uint32 timeElapsed = uint32(block.timestamp) - blockTimestampLast; if (timeElapsed > 0 && reserve0_ > 0 && reserve1_ > 0) { price0CumulativeLast += uint256(UQ112x112.encode(reserve1_).uqdiv(reserve0_)) * timeElapsed; price1CumulativeLast += uint256(UQ112x112.encode(reserve0_).uqdiv(reserve1_)) * timeElapsed; } } reserve0 = uint112(balance0); reserve1 = uint112(balance1); blockTimestampLast = uint32(block.timestamp); emit Sync(reserve0, reserve1); } function _safeTransfer(address token, address to, uint256 value) private { (bool success, bytes memory data) = token.call( abi.encodeWithSignature("transfer(address,uint256)", to, value) ); require( success && (data.length == 0 || abi.decode(data, (bool))), Sls_Error(SlsError.TRANSFER_FAILED) ); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; contract Math { function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint256 y) internal pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; library UQ112x112 { uint224 constant Q112 = 2**112; function encode(uint112 y) internal pure returns (uint224 z) { z = uint224(y) * Q112; } function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { z = x / uint224(y); } }
{ "remappings": [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/", "ds-test/=lib/solmate/lib/ds-test/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": true, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ExcessiveInputAmount","type":"error"},{"inputs":[],"name":"InsufficientAAmount","type":"error"},{"inputs":[],"name":"InsufficientBAmount","type":"error"},{"inputs":[],"name":"InsufficientOutputAmount","type":"error"},{"inputs":[],"name":"SafeTransferFailed","type":"error"},{"inputs":[{"internalType":"enum IErrors.SlsError","name":"errorID","type":"uint8"}],"name":"Sls_Error","type":"error"},{"inputs":[{"internalType":"enum IErrors.SlsError","name":"errorID","type":"uint8"}],"name":"Sls_Library_Error","type":"error"},{"inputs":[{"internalType":"enum IErrors.SlsError","name":"errorID","type":"uint8"}],"name":"Sls_Router_Error","type":"error"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"}]
Deployed Bytecode
0x60806040526004361015610011575f80fd5b5f3560e01c806338ed173914610aef5780635c11d795146106b75780638803dbee14610492578063baa2abde146102fc5763e8e3370014610050575f80fd5b346101c1576101003660031901126101c15761006a610c02565b610072610c18565b60c4356001600160a01b03811692919060643590604435908590036101c15761009f4260e4351015610cdb565b5f546040516334a2a5c360e11b81526001600160a01b038681166004830152858116602483015290911690602081604481855afa9081156101cd575f916102dd575b506001600160a01b031615610270575b505f546001600160a01b031691610109848685611276565b90801580610268575b156101d85750505f9561014a6020949387876101436101386024979a8b959c8d9a610ee1565b978880943390610f99565b3390610f99565b6040516335313c2160e11b815260048101919091529586928391906001600160a01b03165af19081156101cd575f91610194575b6060935060405192835260208301526040820152f35b90506020833d6020116101c5575b816101af60209383610d2c565b810103126101c157606092519061017e565b5f80fd5b3d91506101a2565b6040513d5f823e3d90fd5b6101e68282869594956113cf565b9282841161021e575050505f9561014a60209493878761014361013860249761021360a435821015610d11565b9a8b959c8d9a610ee1565b8261022c93969594506113cf565b908111610254575f9561014a6024928787610143610138602099610213608435871015610cf6565b634e487b7160e01b5f52600160045260245ffd5b508115610112565b6040516364e329cb60e11b81526001600160a01b0386811660048301528516602482015290602090829060449082905f905af180156101cd57156100f1576102cf9060203d6020116102d6575b6102c78183610d2c565b810190610e3f565b505f6100f1565b503d6102bd565b6102f6915060203d6020116102d6576102c78183610d2c565b5f6100e1565b346101c15760e03660031901126101c157610315610c02565b61031d610c18565b60a4356001600160a01b038116908190036101c1576103404260c4351015610cdb565b610395610357838560018060a01b035f5416610ee1565b6040516323b872dd60e01b81523360048201526001600160a01b03919091166024820181905260448035908301529091602090839081906064820190565b03815f855af180156101cd575f93604093602492610465575b508351948593849263226bf2d160e21b845260048401525af19182156101cd575f915f93610427575b50926103e560409482611258565b506001600160a01b0391821691160361042257905b610408606435831015610cf6565b610416608435821015610d11565b82519182526020820152f35b6103fa565b915091506040813d60401161045d575b8161044460409383610d2c565b810103126101c1578051602090910151916103e56103d7565b3d9150610437565b6104869060203d60201161048b575b61047e8183610d2c565b810190610e27565b6103ae565b503d610474565b346101c1576104b06104a336610c2e565b9590929395421115610cdb565b5f546001600160a01b0316946104c7368386610d7a565b6104d5600282511015610e5e565b6104df8151610eaf565b9586515f1981019081116105c8576104f79088610def565b5280515f1981019081116105c857805b6105dc57505084515f1981019081116105c8576105249086610def565b51116105b45780156105a05761053983610e13565b9261054381610e13565b9180600110156105a0576105836105909561057161059c9961058a9661056b60208801610e13565b91610ee1565b61057a89610de2565b51913390610f99565b3691610d7a565b836110ba565b60405191829182610ca2565b0390f35b634e487b7160e01b5f52603260045260245ffd5b632828070d60e11b5f52601560045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f1981018181116105c8576106196001600160a01b036105fc8386610def565b51166001600160a01b036106108587610def565b5116908b611276565b61064b610626858c610def565b518093610634821515610e79565b801515806106ae575b61064690610e94565b61131a565b916103e88302928084046103e814901517156105c85761066a91610dd5565b6103e58102908082046103e514901517156105c8576106889161132d565b90600182018092116105c85761069e9089610def565b5280156105c8575f190180610507565b5083151561063d565b346101c1576106d96106c836610c2e565b959095949194939293421115610cdb565b83156105a0576106e883610e13565b5f546001600160a01b031691906106fe85610e13565b86600110156105a0576107239361071b9161056b60208901610e13565b903390610f99565b5f198301918383116105c8576001600160a01b0361074a610745858785610e03565b610e13565b16604051916370a0823160e01b83526020836024815f60018060a01b038c16968760048401525af19283156101cd575f93610abb575b5061078c368783610d7a565b945f5b86515f1981019081116105c8578110156109d7576001600160a01b036107b58289610def565b511690600181018082116105c8576001600160a01b03906107d6908a610def565b5116916107e38382611258565b505f546001600160a01b03906107fe90869085908416610ee1565b1660405192630240bc6b60e21b8452606084600481855afa9283156101cd575f945f94610995575b506001600160a01b031681149391925f926001600160701b039182169116851561098c5760209091925b6024604051809681936370a0823160e01b83528960048401525af19283156101cd575f93610957575b506108878161088c94610dd5565b61134b565b9115610950575f91935b8a5160011981019081116105c8578410156109485760018060a01b035f541660028501918286116105c8576108e0926001600160a01b03906108d8908f610def565b511691610ee1565b905b803b156101c1576040516336cd320560e11b8152600481019390935260248301949094526001600160a01b03166044820152915f908390606490829084905af19182156101cd57600192610938575b500161078f565b5f61094291610d2c565b8a610931565b508b906108e2565b5f93610896565b92506020833d8211610984575b8161097160209383610d2c565b810103126101c157915191610887610879565b3d9150610964565b91602090610850565b6001600160701b0395505f9394506109c4869160603d81116109d0575b6109bc8183610d2c565b810190611222565b50909650949350610826565b503d6109b2565b509160246020926109f56107455f97968b60018060a01b0394610e03565b169160405195869384926370a0823160e01b845260048401525af180156101cd575f90610a87575b610a279250610dd5565b10610a2e57005b60405162461bcd60e51b815260206004820152602b60248201527f556e69737761705632526f757465723a20494e53554646494349454e545f4f5560448201526a1514155517d05353d5539560aa1b6064820152608490fd5b506020823d602011610ab3575b81610aa160209383610d2c565b810103126101c157610a279151610a1d565b3d9150610a94565b9092506020813d602011610ae7575b81610ad760209383610d2c565b810103126101c157519187610780565b3d9150610aca565b346101c157610b10610b0036610c2e565b9590929195949394421115610cdb565b5f546001600160a01b031691610b27368784610d7a565b95610b36600288511015610e5e565b610b408751610eaf565b94610b4a86610de2565b525f5b87515f1981019081116105c857811015610bbd576001600160a01b03610b73828a610def565b511690600181018082116105c857610bb6610baf610b9e6001958d61061086898060a01b0392610def565b90610ba9868d610def565b5161134b565b9189610def565b5201610b4d565b509091929484515f1981019081116105c857610bd99086610def565b5110610bee5780156105a05761053983610e13565b632828070d60e11b5f52600c60045260245ffd5b600435906001600160a01b03821682036101c157565b602435906001600160a01b03821682036101c157565b9060a06003198301126101c157600435916024359160443567ffffffffffffffff81116101c157826023820112156101c15780600401359267ffffffffffffffff84116101c15760248460051b830101116101c15760240191906064356001600160a01b03811681036101c1579060843590565b60206040818301928281528451809452019201905f5b818110610cc55750505090565b8251845260209384019390920191600101610cb8565b15610ce257565b632828070d60e11b5f52600960045260245ffd5b15610cfd57565b632828070d60e11b5f52600d60045260245ffd5b15610d1857565b632828070d60e11b5f52600e60045260245ffd5b90601f8019910116810190811067ffffffffffffffff821117610d4e57604052565b634e487b7160e01b5f52604160045260245ffd5b67ffffffffffffffff8111610d4e5760051b60200190565b9291610d8582610d62565b93610d936040519586610d2c565b602085848152019260051b81019182116101c157915b818310610db557505050565b82356001600160a01b03811681036101c157815260209283019201610da9565b919082039182116105c857565b8051156105a05760200190565b80518210156105a05760209160051b010190565b91908110156105a05760051b0190565b356001600160a01b03811681036101c15790565b908160209103126101c1575180151581036101c15790565b908160209103126101c157516001600160a01b03811681036101c15790565b15610e6557565b63ef0bf2bd60e01b5f52600f60045260245ffd5b15610e8057565b63ef0bf2bd60e01b5f52600c60045260245ffd5b15610e9b57565b63ef0bf2bd60e01b5f52600a60045260245ffd5b90610eb982610d62565b610ec66040519182610d2c565b8281528092610ed7601f1991610d62565b0190602036910137565b91610eeb91611258565b6040519060208201926001600160601b03199060601b1683526001600160601b03199060601b16603482015260288152610f26604882610d2c565b519020906120d4604051610f3d6020830182610d2c565b8181526020810191611411833951902060405192602084019260ff60f81b84526001600160601b03199060601b1660218501526035840152605583015260558252610f89607583610d2c565b905190206001600160a01b031690565b6040516323b872dd60e01b602082019081526001600160a01b0393841660248301529390921660448301526064808301949094529281525f92839290918390610fe3608482610d2c565b51925af13d156110b3573d67ffffffffffffffff8111610d4e5760405190611015601f8201601f191660200183610d2c565b81523d5f602083013e5b81611084575b501561102d57565b60405162461bcd60e51b815260206004820152602960248201527f5472616e7366657248656c7065723a20534146455f5452414e534645525f465260448201526813d357d1905253115160ba1b6064820152608490fd5b8051801592508215611099575b50505f611025565b6110ac9250602080918301019101610e27565b5f80611091565b606061101f565b909291925f5b81515f1981019081116105c857811015611207576001600160a01b036110e68284610def565b511690600181018082116105c8576001600160a01b036111068286610def565b511661111d6111158286611258565b509287610def565b51916001600160a01b03168403611200575f91935b855160011981019081116105c8578410156111f6575f546001600160a01b0316600285018086116105c85761118f9161117a9185906001600160a01b03906108d8908c610def565b925b5f546001600160a01b0393908416610ee1565b16803b156101c1576040516336cd320560e11b8152600481019390935260248301949094526001600160a01b03166044820152915f908390606490829084905af19182156101cd576001926111e6575b50016110c0565b5f6111f091610d2c565b5f6111df565b61118f899261117c565b5f93611132565b5050509050565b51906001600160701b03821682036101c157565b908160609103126101c1576112368161120e565b9160406112456020840161120e565b92015163ffffffff811681036101c15790565b9091906001600160a01b038084169082161015611273579190565b90565b90606060049261128961129e9584611258565b90956001600160a01b03929091908790610ee1565b1660405193848092630240bc6b60e21b82525afa9182156101cd575f905f936112eb575b506001600160701b03928316939216916001600160a01b039182169116036112e75791565b9091565b6001600160701b0393508391506113109060603d6060116109d0576109bc8183610d2c565b50939091506112c2565b818102929181159184041417156105c857565b8115611337570490565b634e487b7160e01b5f52601260045260245ffd5b80156113bb578115928315806113b2575b61136590610e94565b6103e582029182046103e5036105c85761137f908261131a565b926103e883029283046103e81417156105c85781018091116105c8576113a49161132d565b906113b0821515610e79565b565b5080151561135c565b63ef0bf2bd60e01b5f52600b60045260245ffd5b80156113fc57611273926113ee91831515806113f35761064690610e94565b61132d565b5081151561063d565b63ef0bf2bd60e01b5f52600d60045260245ffdfe60e0604052346103d8576040516100176040826103dc565b6006815265534c5320563160d01b60208201526040516100386040826103dc565b6006815265534c532d563160d01b602082015281516001600160401b03811161030b576100655f546103ff565b601f8111610389575b50602092601f821160011461032a57928192935f9261031f575b50508160011b915f199060031b1c1916175f555b80516001600160401b03811161030b576100b76001546103ff565b601f81116102a8575b50602091601f8211600114610248579181925f9261023d575b50508160011b915f199060031b1c1916176001555b60126080524660a0526040515f905f549181610109846103ff565b9182825260208201946001811690815f1461022157506001146101d7575b610133925003826103dc565b51902060405160208101917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f835260408201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260a081526101a760c0826103dc565b51902060c052604051611c7c90816104388239608051816112af015260a05181611639015260c0518161165f0152f35b505f80805290915f805160206120b48339815191525b81831061020557505090602061013392820101610127565b60209193508060019154838588010152019101909183926101ed565b60ff191686525061013392151560051b82016020019050610127565b015190505f806100d9565b601f1982169260015f52805f20915f5b85811061029057508360019510610278575b505050811b016001556100ee565b01515f1960f88460031b161c191690555f808061026a565b91926020600181928685015181550194019201610258565b60015f527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6601f830160051c81019160208410610301575b601f0160051c01905b8181106102f657506100c0565b5f81556001016102e9565b90915081906102e0565b634e487b7160e01b5f52604160045260245ffd5b015190505f80610088565b601f198216935f8052805f20915f5b8681106103715750836001959610610359575b505050811b015f5561009c565b01515f1960f88460031b161c191690555f808061034c565b91926020600181928685015181550194019201610339565b5f80525f805160206120b4833981519152601f830160051c810191602084106103ce575b601f0160051c01905b8181106103c3575061006e565b5f81556001016103b6565b90915081906103ad565b5f80fd5b601f909101601f19168101906001600160401b0382119082101761030b57604052565b90600182811c9216801561042d575b602083101461041957565b634e487b7160e01b5f52602260045260245ffd5b91607f169161040e56fe60806040526004361015610011575f80fd5b5f3560e01c806306fdde03146114a15780630902f1ac14611461578063095ea7b3146113e85780630dfe1681146113c057806318160ddd146113a357806323b872dd146112d3578063313ce567146112965780633644e51514611274578063485cc955146111e55780635909c0d5146111c85780635a3d5493146111ab5780636a62784214610f245780636d9a640a14610b8157806370a0823114610b495780637464fc3d14610b2c5780637ecebe0014610af457806389afcb441461079a57806395d89b41146106c0578063a9059cbb1461064b578063bc25cf77146104ff578063c45a0155146104d7578063d21220a7146104af578063d505accf146102b0578063dd62ed3e146102605763fff6cae91461012c575f80fd5b34610217575f366003190112610217576001600d5461014e60ff8216156117b0565b60ff191617600d555f61015f611607565b5090602060018060a01b03600754166024604051809681936370a0823160e01b83523060048401525af18015610223575f9061022e575b6008546040516370a0823160e01b81523060048201529450602090859060249082905f906001600160a01b03165af1908115610223575f916101e9575b6101dd94506119d7565b600d805460ff19169055005b90506020843d60201161021b575b816102046020938361157b565b81010312610217576101dd9351906101d3565b5f80fd5b3d91506101f7565b6040513d5f823e3d90fd5b506020833d602011610258575b816102486020938361157b565b81010312610217575f9251610196565b3d915061023b565b34610217576040366003190112610217576102796115db565b6102816115f1565b6001600160a01b039182165f908152600460209081526040808320949093168252928352819020549051908152f35b346102175760e0366003190112610217576102c96115db565b6102d16115f1565b6044356064359260843560ff81168091036102175742851061046a5760805f916020936102fc611636565b9060018060a01b03169687855260058652604085209889549960018b01905560405190878201927f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c984528a604084015260018060a01b03169a8b6060840152898784015260a083015260c082015260c0815261037960e08261157b565b519020604051908682019261190160f01b845260228301526042820152604281526103a560628261157b565b519020906040519182528482015260a435604082015260c435606082015282805260015afa15610223575f516001600160a01b031680151580610461575b1561042b577f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925916020915f526004825260405f20855f5282528060405f2055604051908152a3005b60405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606490fd5b508281146103e3565b60405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606490fd5b34610217575f366003190112610217576008546040516001600160a01b039091168152602090f35b34610217575f366003190112610217576006546040516001600160a01b039091168152602090f35b34610217576020366003190112610217576105186115db565b6001600d5461052a60ff8216156117b0565b60ff191617600d556007546008546040516370a0823160e01b81523060048201526001600160a01b03918216929091166020826024815f855af19182156102235784905f93610613575b5061058e610594936001600160701b036009541690611629565b91611afb565b6040516370a0823160e01b8152306004820152916020836024815f865af1928315610223575f936105dd575b5061058e6101dd936001600160701b0360095460701c1690611629565b92506020833d60201161060b575b816105f86020938361157b565b810103126102175791519161058e6105c0565b3d91506105eb565b9250506020823d602011610643575b8161062f6020938361157b565b81010312610217579051908361058e610574565b3d9150610622565b34610217576040366003190112610217576106646115db565b60243590335f52600360205260405f2061067f838254611629565b905560018060a01b031690815f52600360205260405f208181540190556040519081525f80516020611c2783398151915260203392a3602060405160018152f35b34610217575f366003190112610217576040515f6001546106e081611543565b80845290600181169081156107765750600114610718575b610714836107088185038261157b565b604051918291826115b1565b0390f35b60015f9081527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6939250905b80821061075c575090915081016020016107086106f8565b919260018160209254838588010152019101909291610744565b60ff191660208086019190915291151560051b8401909101915061070890506106f8565b34610217576020366003190112610217576107b36115db565b6001600d546107c560ff8216156117b0565b60ff191617600d555f6107d6611607565b509092602060018060a01b03600754166024604051809681936370a0823160e01b83523060048401525af1918215610223575f92610ac0575b6008546040516370a0823160e01b81523060048201529450602090859060249082905f906001600160a01b03165af1938415610223575f94610a8c575b50305f52600360205260405f20549461088a61087e61087e6108836108718686611809565b976002549384918c6117cb565b6117de565b97896117cb565b9385151580610a83575b15610a6f575f80973082526003602052604082206108b3828254611629565b905580600254036002556040519081525f80516020611c2783398151915260203092a36007546108ef90879086906001600160a01b0316611afb565b60085461090890869086906001600160a01b0316611afb565b6007546040516370a0823160e01b81523060048201529760209189916024918391906001600160a01b03165af1968715610223575f97610a3b575b506008546040516370a0823160e01b815230600482015290602090829060249082905f906001600160a01b03165af1908115610223575f91610a09575b50838361098f9260409a6119d7565b6109ea575b505083519083825282602083015260018060a01b0316848201527fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d8193649660603392a260ff19600d5416600d5582519182526020820152f35b6001600160701b03806109ff931691166117cb565b600c558480610994565b90506020813d602011610a33575b81610a246020938361157b565b81010312610217575183610980565b3d9150610a17565b9096506020813d602011610a67575b81610a576020938361157b565b8101031261021757519587610943565b3d9150610a4a565b637a52fb5d60e01b5f52601260045260245ffd5b50841515610894565b9093506020813d602011610ab8575b81610aa86020938361157b565b810103126102175751928561084c565b3d9150610a9b565b91506020833d602011610aec575b81610adb6020938361157b565b81010312610217575f92519161080f565b3d9150610ace565b34610217576020366003190112610217576001600160a01b03610b156115db565b165f526005602052602060405f2054604051908152f35b34610217575f366003190112610217576020600c54604051908152f35b34610217576020366003190112610217576001600160a01b03610b6a6115db565b165f526003602052602060405f2054604051908152f35b34610217576060366003190112610217576044356001600160a01b038116906004359060243590838103610217576001600d54610bc160ff8216156117b0565b60ff191617600d5582159081158092610f1b575b15610f0757610be2611607565b50916001600160701b0382169081871080610ef5575b15610ee1575f94610ec3575b8580610ea6575b50506007546040516370a0823160e01b81523060048201529460209186916024918391906001600160a01b03165af1938415610223575f94610e72575b506008546040516370a0823160e01b81523060048201529190602090839060249082905f906001600160a01b03165af1918215610223575f92610e3e575b50600954866001600160701b03821689610ca08183611629565b891115610e2d57610cbc610cc2916001600160701b0393611629565b89611629565b925b60701c16610cd28282611629565b851115610e2457610cec91610ce691611629565b84611629565b905b801590811582610e1b575b15610e07576103e88802918883046103e81489151715610df357600382029182046003141715610df357610d2c91611629565b906103e88402918483046103e81485151715610df357600382029180830460031490151715610df357610d65610d6b92610d7c94611629565b906117cb565b916001600160701b038616906117cb565b90620f4240820291808304620f42401490151715610df35710610ddf57610da2936119d7565b60405191825260208201527f2a9237ff5aa599ef4c5ee4b1142b53429d5755e2685fe6288b2e3320202115f560403392a3600d805460ff19169055005b637a52fb5d60e01b5f52601460045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b637a52fb5d60e01b5f52600b60045260245ffd5b50821515610cf9565b50505f90610cee565b50506001600160701b035f92610cc4565b9091506020813d602011610e6a575b81610e5a6020938361157b565b8101031261021757519088610c86565b3d9150610e4d565b9093506020813d602011610e9e575b81610e8e6020938361157b565b810103126102175751925f610c48565b3d9150610e81565b600854610ebc92906001600160a01b0316611afb565b8785610c0b565b600754610edc90889083906001600160a01b0316611afb565b610c04565b637a52fb5d60e01b5f52600a60045260245ffd5b506001600160701b0384168610610bf8565b637a52fb5d60e01b5f52600c60045260245ffd5b50821515610bd5565b3461021757602036600319011261021757610f3d6115db565b6001600d54610f4f60ff8216156117b0565b60ff191617600d555f610f60611607565b509290602060018060a01b03600754166024604051809681936370a0823160e01b83523060048401525af1928315610223575f93611177575b506008546040516370a0823160e01b815230600482015290602090829060249082905f906001600160a01b03165af1908115610223575f91611145575b506001600160701b03821692610fec8486611629565b936001600160701b038716906110028285611629565b9161100d8987611809565b6002548883858361111357505061102e915085611029916117cb565b61193e565b6103e7198101908111610df357986002546103e88101809111610df3576002555f8052600360205260405f206103e881540190555f805f80516020611c2783398151915260206040516103e88152a35b89156110ff5760209a7f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f986040986110bf936110ba8e8b611993565b6119d7565b6110ec575b50508251948552868501526001600160a01b031692a260ff19600d5416600d55604051908152f35b6110f5916117cb565b600c5587806110c4565b637a52fb5d60e01b5f52601060045260245ffd5b61112761087e9161087e8661112e966117cb565b93886117cb565b8082101561113e57505b9861107e565b9050611138565b90506020813d60201161116f575b816111606020938361157b565b81010312610217575185610fd6565b3d9150611153565b9092506020813d6020116111a3575b816111936020938361157b565b8101031261021757519184610f99565b3d9150611186565b34610217575f366003190112610217576020600b54604051908152f35b34610217575f366003190112610217576020600a54604051908152f35b34610217576040366003190112610217576111fe6115db565b6112066115f1565b60075490916001600160a01b0382161580611261575b1561124d576001600160a01b03199182166001600160a01b0391821617600755600880549092169216919091179055005b637a52fb5d60e01b5f52601660045260245ffd5b506008546001600160a01b03161561121c565b34610217575f36600319011261021757602061128e611636565b604051908152f35b34610217575f36600319011261021757602060405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610217576060366003190112610217576112ec6115db565b6112f46115f1565b6001600160a01b039091165f818152600460209081526040808320338452825290912054604435935f80516020611c278339815191529291856001820161137e575b5050835f526003825260405f2061134e868254611629565b90556001600160a01b03165f818152600383526040908190208054870190555194855293a3602060405160018152f35b61138791611629565b5f85815260048452604080822033835285529020558585611336565b34610217575f366003190112610217576020600254604051908152f35b34610217575f366003190112610217576007546040516001600160a01b039091168152602090f35b34610217576040366003190112610217576114016115db565b335f8181526004602090815260408083206001600160a01b03909516808452948252918290206024359081905591519182527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a3602060405160018152f35b34610217575f3660031901126102175760606001600160701b0363ffffffff611488611607565b9193908160405195168552166020840152166040820152f35b34610217575f366003190112610217576040515f80546114c081611543565b808452906001811690811561077657506001146114e757610714836107088185038261157b565b5f8080527f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563939250905b808210611529575090915081016020016107086106f8565b919260018160209254838588010152019101909291611511565b90600182811c92168015611571575b602083101461155d57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691611552565b90601f8019910116810190811067ffffffffffffffff82111761159d57604052565b634e487b7160e01b5f52604160045260245ffd5b602060409281835280519182918282860152018484015e5f828201840152601f01601f1916010190565b600435906001600160a01b038216820361021757565b602435906001600160a01b038216820361021757565b6009546001600160701b038116916001600160701b038260701c169160e01c90565b91908203918211610df357565b467f000000000000000000000000000000000000000000000000000000000000000003611681577f000000000000000000000000000000000000000000000000000000000000000090565b6040515f905f54918161169384611543565b9182825260208201946001811690815f146117945750600114611737575b6116bd9250038261157b565b51902060405160208101917f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f835260408201527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260a0815261173160c08261157b565b51902090565b505f80805290917f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5635b8183106117785750509060206116bd928201016116b1565b6020919350806001915483858801015201910190918392611760565b60ff19168652506116bd92151560051b820160200190506116b1565b156117b757565b637a52fb5d60e01b5f52600660045260245ffd5b81810292918115918404141715610df357565b81156117e8570490565b634e487b7160e01b5f52601260045260245ffd5b91908201809211610df357565b60065460405163ae2e933b60e01b81529293929190602090839060049082906001600160a01b03165afa918215610223575f926118fa575b50600c546001600160a01b038316158015959192906118ea5782611866575b50505050565b611029611882916001600160701b0380611888951691166117cb565b9161193e565b90818111611897575b80611860565b6118a7600254610d658484611629565b90600581029080820460051490151715610df3576118ce926118c8916117fc565b906117de565b806118da575b80611891565b6118e391611993565b5f806118d4565b505090506118f457565b5f600c55565b9091506020813d602011611936575b816119166020938361157b565b8101031261021757516001600160a01b038116810361021757905f611841565b3d9150611909565b905f60038311156119865750818060011c60018101809111610df357905b838210611967575050565b90925061197d8361197881846117de565b6117fc565b60011c9061195c565b9161198d57565b60019150565b5f80516020611c2783398151915260205f926119b1856002546117fc565b6002556001600160a01b03168084526003825260408085208054870190555194855293a3565b91926001600160701b0383111580611aea575b15611ad6576001600160701b0360409381927fcf2aa50876cdfbb541206f89af0ee78d44a2abf8d328e37fa4917f982149848a9663ffffffff60095460e01c81421603169182151580611acb575b80611ac0575b611a77575b50505016918263ffffffff60e01b4260e01b16918360701b9060701b16171780600955835192835260701c166020820152a1565b611aaf90836001600160e01b03611a9685611a9185611bd2565b611c08565b1602600a5401600a55611a9160018060e01b0393611bd2565b1602600b5401600b555f8080611a43565b508481161515611a3e565b508482161515611a38565b637a52fb5d60e01b5f52601160045260245ffd5b506001600160701b038211156119ea565b5f929183809360405190602082019363a9059cbb60e01b855260018060a01b03166024830152604482015260448152611b3560648261157b565b51925af13d15611bcb573d67ffffffffffffffff811161159d5760405190611b67601f8201601f19166020018361157b565b81523d5f602083013e5b81611b93575b5015611b7f57565b637a52fb5d60e01b5f52600860045260245ffd5b8051801592508215611ba8575b50505f611b77565b819250906020918101031261021757602001518015158103610217575f80611ba0565b6060611b71565b6dffffffffffffffffffffffffffff60701b607082901b16906001600160701b0316808204600160701b1490151715610df35790565b906001600160701b03169081156117e8576001600160e01b0316049056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122000154d6591ec72bcb4d8a8349816d12ac4f31c384a167f9c3e58ff843ee0ff0664736f6c634300081a0033290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563a26469706673582212208b3e17bdb5785e9faffdb7a1bae0d7e164ee3ddaa34cfe8176a880cd8ab2a51f64736f6c634300081a0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.