Contract Overview
[ Download CSV Export ]
Latest 1 internal transaction
Parent Txn Hash | Block | From | To | Value | |||
---|---|---|---|---|---|---|---|
0xf76f022003e5e6512ba85823865b2955911700534134fe83d773dd491761e0ed | 26299865 | 435 days 9 hrs ago | Tetu: TetuSwap Factory | Contract Creation | 0 MATIC |
[ Download CSV Export ]
Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0xEFeAe25C62574e2652B24E6215000c2C7a2473aB
Contract Name:
TetuSwapPair
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 150 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "./TetuSwapERC20.sol"; import "./libraries/UQ112x112.sol"; import "./libraries/Math.sol"; import "./libraries/TetuSwapLibrary.sol"; import "../third_party/uniswap/IUniswapV2Callee.sol"; import "../third_party/uniswap/IUniswapV2Factory.sol"; import "../third_party/IERC20Name.sol"; import "../base/interface/ISmartVault.sol"; import "./interfaces/ITetuSwapPair.sol"; /// @title Tetu swap pair based on Uniswap solution /// Invest underlying assets to Tetu SmartVaults /// @author belbix contract TetuSwapPair is TetuSwapERC20, ITetuSwapPair, ReentrancyGuard { using SafeERC20 for IERC20; using UQ112x112 for uint224; // ********** CONSTANTS ******************** /// @notice Version of the contract /// @dev Should be incremented when contract changed string public constant VERSION = "1.0.0"; uint public constant PRECISION = 10000; uint public constant MAX_FEE = 30; uint public constant override MINIMUM_LIQUIDITY = 10 ** 3; // ********** VARIABLES ******************** address public override factory; address public override rewardRecipient; address public override token0; address public override token1; address public override vault0; address public override vault1; uint112 private reserve0; uint112 private reserve1; uint32 private blockTimestampLast; // uses single storage slot, accessible via getReserves uint public override price0CumulativeLast; uint public override price1CumulativeLast; string private _symbol; uint public override fee; uint public createdTs; uint public createdBlock; // ********** EVENTS ******************** 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); event FeeChanged(uint oldFee, uint newFee); event VaultsChanged(address vault0, address vault1); event RewardRecipientChanged(address oldRecipient, address newRecipient); event Claimed(uint blockTs); /// @dev Should be create only from factory constructor() { factory = msg.sender; } modifier onlyFactory() { require(msg.sender == factory, "TSP: Not factory"); _; } /// @dev Called once by the factory at time of deployment function initialize( address _token0, address _token1, uint _fee ) external override onlyFactory { require(_fee <= MAX_FEE, "TSP: Too high fee"); require(token0 == address(0), "TSP: Already initialized"); require(token1 == address(0), "TSP: Already initialized"); token0 = _token0; token1 = _token1; fee = _fee; _symbol = createPairSymbol(IERC20Name(_token0).symbol(), IERC20Name(_token1).symbol()); createdTs = block.timestamp; createdBlock = block.number; } function symbol() external override view returns (string memory) { return _symbol; } /// @dev Return saved reserves. Be aware that reserves always fluctuate! /// For actual values need to call update function getReserves() public view override returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) { _reserve0 = reserve0; _reserve1 = reserve1; _blockTimestampLast = blockTimestampLast; } /// @dev Update reserves and, on the first call per block, price accumulators function _update() private { uint _balance0 = vaultReserve0(); uint _balance1 = vaultReserve1(); require(_balance0 <= type(uint112).max && _balance1 <= type(uint112).max, "TSP: OVERFLOW"); uint32 blockTimestamp = uint32(block.timestamp % 2 ** 32); uint32 timeElapsed = blockTimestamp - blockTimestampLast; if (timeElapsed > 0 && reserve0 != 0 && reserve1 != 0) { price0CumulativeLast += uint(UQ112x112.encode(reserve1).uqdiv(reserve0)) * timeElapsed; price1CumulativeLast += uint(UQ112x112.encode(reserve0).uqdiv(reserve1)) * timeElapsed; } reserve0 = uint112(_balance0); reserve1 = uint112(_balance1); blockTimestampLast = blockTimestamp; emit Sync(reserve0, reserve1); } /// @dev Assume underlying tokens already sent to this contract /// Mint new LP tokens to sender. Based on vault shares function mint(address to) external nonReentrant override returns (uint liquidity) { uint shareAmount0 = IERC20(vault0).balanceOf(address(this)); uint shareAmount1 = IERC20(vault1).balanceOf(address(this)); uint underlyingAmount0 = depositAllToVault(vault0); uint underlyingAmount1 = depositAllToVault(vault1); uint depositedAmount0 = IERC20(vault0).balanceOf(address(this)) - shareAmount0; uint depositedAmount1 = IERC20(vault1).balanceOf(address(this)) - shareAmount1; uint _totalSupply = totalSupply; if (_totalSupply == 0) { liquidity = Math.sqrt(depositedAmount0 * depositedAmount1) - MINIMUM_LIQUIDITY; // permanently lock the first MINIMUM_LIQUIDITY tokens _mint(address(0), MINIMUM_LIQUIDITY); } else { liquidity = Math.min( depositedAmount0 * _totalSupply / shareAmount0, depositedAmount1 * _totalSupply / shareAmount1 ); } require(liquidity > 0, "TSP: Insufficient liquidity minted"); _mint(to, liquidity); _update(); emit Mint(msg.sender, underlyingAmount0, underlyingAmount1); } /// @dev Assume lp token already sent to this contract /// Burn LP tokens and send back underlying assets. Based on vault shares function burn(address to) external nonReentrant override returns (uint amount0, uint amount1) { uint shareAmount0 = IERC20(vault0).balanceOf(address(this)); uint shareAmount1 = IERC20(vault1).balanceOf(address(this)); uint liquidity = balanceOf[address(this)]; uint shareToWithdraw0 = liquidity * shareAmount0 / totalSupply; uint shareToWithdraw1 = liquidity * shareAmount1 / totalSupply; require(shareToWithdraw0 > 0 && shareToWithdraw1 > 0, "TSP: Insufficient liquidity burned"); _burn(address(this), liquidity); require(shareToWithdraw0 <= IERC20(vault0).balanceOf(address(this)), "TSP: Insufficient shares 0"); require(shareToWithdraw1 <= IERC20(vault1).balanceOf(address(this)), "TSP: Insufficient shares 1"); ISmartVault(vault0).withdraw(shareToWithdraw0); ISmartVault(vault1).withdraw(shareToWithdraw1); amount0 = IERC20(token0).balanceOf(address(this)); amount1 = IERC20(token1).balanceOf(address(this)); IERC20(token0).safeTransfer(to, amount0); IERC20(token1).safeTransfer(to, amount1); _update(); emit Burn(msg.sender, amount0, amount1, to); } /// @dev Assume tokenIn already sent to this contract /// During swap process underlying assets will be deposited and withdrew from vaults /// Depends on vault logic, underlying asset can be deposited with little reducing of amount /// For keeping healthy K we are auto-compounding 1/10 of fees function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external nonReentrant override { require(amount0Out > 0 || amount1Out > 0, "TSP: Insufficient output amount"); (uint112 _reserve0, uint112 _reserve1,) = getReserves(); require(amount0Out < _reserve0 && amount1Out < _reserve1, "TSP: Insufficient liquidity"); uint expectedAmountIn0 = getAmountIn(amount1Out, _reserve0, _reserve1); uint expectedAmountIn1 = getAmountIn(amount0Out, _reserve1, _reserve0); // assume we invested all funds and have on balance only new tokens for current swap uint amount0In = IERC20(token0).balanceOf(address(this)); uint amount1In = IERC20(token1).balanceOf(address(this)); // check amountIn for cases of vault reserves fluctuations // we check accurate input value with required fees require(amount0In >= expectedAmountIn0 && amount1In >= expectedAmountIn1, "TSP: Insufficient input amount"); if (amount0In > 0) { ISmartVault(vault0).deposit(amount0In); } if (amount1In > 0) { ISmartVault(vault1).deposit(amount1In); } {// scope for optimistically transfer output amount uint amountFee = 0; if (amount0In > amount1In) { amountFee = getFeeAmount(amount0In, _reserve0, _reserve1, amount1Out); } else { amountFee = getFeeAmount(amount1In, _reserve1, _reserve0, amount0Out); } _optimisticallyTransfer(amount0Out, amount1Out, to, data, amountFee); } // K value should be in a healthy range // in a normal circumstance not required after input amount checking // but kept for excluding for any possibilities of vault reserve manipulation {// scope for K checking uint balance0 = vaultReserve0(); uint balance1 = vaultReserve1(); // check K without fees require(balance0 * balance1 >= uint(_reserve0) * uint(_reserve1), "TSP: K too low"); } _update(); emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to); } /// @dev Force update function sync() external nonReentrant override { _update(); } // ****************************************************** // ************ NON UNISWAP FUNCTIONS ******************* // ****************************************************** /// @dev Returns expected input amount for given output amount function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) public view returns (uint amountIn){ if (amountOut == 0) { return 0; } return TetuSwapLibrary.getAmountIn(amountOut, reserveIn, reserveOut, fee); } /// @dev Calculates fee amount assuming that amountOutWithFee includes actual fee /// Keep 1/10 of fee for auto-compounding /// In case of 0 fees we will not able to use vaults with deposited amount fluctuations function getFeeAmount(uint amountIn, uint reserveIn, uint reserveOut, uint amountOutWithFee) public pure returns (uint amountFee){ if (amountIn == 0) { return 0; } uint amountOutWithoutFee = TetuSwapLibrary.getAmountOut(amountIn, reserveIn, reserveOut, 0); if (amountOutWithoutFee <= amountOutWithFee) { return 0; } // keep 10% for auto compounding amountFee = (amountOutWithoutFee - amountOutWithFee) * 9 / 10; } /// @dev Returns vault underlying balance, or zero if it is not a underlying token function balanceOfVaultUnderlying(address _token) external view override returns (uint){ if (_token == ISmartVault(vault0).underlying()) { return ISmartVault(vault0).underlyingBalanceWithInvestmentForHolder(address(this)); } else if (_token == ISmartVault(vault1).underlying()) { return ISmartVault(vault1).underlyingBalanceWithInvestmentForHolder(address(this)); } return 0; } /// @dev Returns vault underlying balance for this contract function vaultReserve0() public view returns (uint112) { return uint112(ISmartVault(vault0).underlyingBalanceWithInvestmentForHolder(address(this))); } /// @dev Returns vault underlying balance for this contract function vaultReserve1() public view returns (uint112){ return uint112(ISmartVault(vault1).underlyingBalanceWithInvestmentForHolder(address(this))); } // ********* GOVERNANCE FUNCTIONS **************** /// @dev Set fee in range 0-0.3% function setFee(uint _fee) external override onlyFactory { require(_fee <= MAX_FEE, "TSP: Too high fee"); emit FeeChanged(fee, _fee); fee = _fee; } /// @dev Called by fee setter after pair initialization function setVaults(address _vault0, address _vault1) external override onlyFactory { require(ISmartVault(_vault0).underlying() == token0, "TSP: Wrong vault0 underlying"); require(ISmartVault(_vault1).underlying() == token1, "TSP: Wrong vault1 underlying"); exitFromVault(vault0); exitFromVault(vault1); vault0 = _vault0; vault1 = _vault1; IERC20(token0).safeApprove(_vault0, type(uint).max); IERC20(token1).safeApprove(_vault1, type(uint).max); depositAllToVault(vault0); depositAllToVault(vault1); emit VaultsChanged(vault0, vault1); } /// @dev Set rewards recipient. This address will able to claim vault rewards and get swap fees function setRewardRecipient(address _recipient) external override onlyFactory { emit RewardRecipientChanged(rewardRecipient, _recipient); rewardRecipient = _recipient; } /// @dev Only reward recipient able to call it /// Claims vaults rewards and send it to recipient function claimAll() external override { require(msg.sender == rewardRecipient, "TSP: Only recipient can claim"); _claim(vault0); _claim(vault1); emit Claimed(block.timestamp); } // ***************** INTERNAL LOGIC **************** /// @dev Transfers output amount + fees function _optimisticallyTransfer( uint amount0Out, uint amount1Out, address to, bytes calldata data, uint amountFee ) private { address _token0 = token0; address _token1 = token1; require(to != _token0 && to != _token1, "TSP: Invalid to"); if (amount0Out > 0) { withdrawFromVault(vault0, amount0Out + amountFee); IERC20(_token0).safeTransfer(to, amount0Out); if (amountFee > 0) { IERC20(_token0).safeTransfer(rewardRecipient, amountFee); } } if (amount1Out > 0) { withdrawFromVault(vault1, amount1Out + amountFee); IERC20(_token1).safeTransfer(to, amount1Out); if (amountFee > 0) { IERC20(_token1).safeTransfer(rewardRecipient, amountFee); } } if (data.length > 0) { IUniswapV2Callee(to).uniswapV2Call(msg.sender, amount0Out, amount1Out, data); } } /// @dev Deposit all underlying tokens to given vault function depositAllToVault(address _vault) private returns (uint) { uint underlyingAmount = IERC20(ISmartVault(_vault).underlying()).balanceOf(address(this)); if (underlyingAmount > 0) { ISmartVault(_vault).deposit(underlyingAmount); } return underlyingAmount; } /// @dev Exit from given vault and set approve to zero for underlying token function exitFromVault(address _vault) private { if (_vault == address(0)) { return; } uint balance = IERC20(_vault).balanceOf(address(this)); if (balance > 0) { ISmartVault(_vault).withdraw(balance); } IERC20(ISmartVault(_vault).underlying()).safeApprove(_vault, 0); } /// @dev Withdraw approx amount of underlying amount from given vault function withdrawFromVault(address _vault, uint _underlyingAmount) private { ISmartVault sv = ISmartVault(_vault); uint shareBalance = IERC20(_vault).balanceOf(address(this)); uint shareToWithdraw = _underlyingAmount * sv.underlyingUnit() / sv.getPricePerFullShare(); // add 1 for avoiding rounding issues shareToWithdraw = Math.min(shareToWithdraw + 1, shareBalance); require(shareToWithdraw <= shareBalance, "TSP: Insufficient shares"); sv.withdraw(shareToWithdraw); } /// @dev Creates symbol string from given names function createPairSymbol(string memory name0, string memory name1) private pure returns (string memory) { return string(abi.encodePacked("TLP_", name0, "_", name1)); } /// @dev Claim all rewards from given vault and send to reward recipient function _claim(address _vault) private { require(_vault != address(0), "TSP: Zero vault"); ISmartVault sv = ISmartVault(_vault); for (uint i = 0; i < sv.rewardTokensLength(); i++) { address rt = sv.rewardTokens()[i]; uint bal = IERC20(rt).balanceOf(address(this)); sv.getReward(rt); uint claimed = IERC20(rt).balanceOf(address(this)) - bal; if (claimed > 0) { IERC20(rt).safeTransfer(rewardRecipient, claimed); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; /// @title Uniswap implementation of ERC20 token with permit /// https://github.com/Uniswap/v2-core/blob/master/contracts/UniswapV2ERC20.sol abstract contract TetuSwapERC20 { // ******** CONSTANTS **************** string private constant DEFAULT_SYMBOL = "TLP"; string public constant name = "TetuSwap LP"; uint8 public constant decimals = 18; // ******** VARIABLES **************** uint public totalSupply; mapping(address => uint) public balanceOf; mapping(address => mapping(address => uint)) public allowance; bytes32 public DOMAIN_SEPARATOR; // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; mapping(address => uint) public nonces; // ******** EVENTS ****************** event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); constructor() { uint _chainId; assembly { _chainId := chainid() } DOMAIN_SEPARATOR = keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256(bytes("1")), _chainId, address(this) ) ); } function symbol() external virtual view returns (string memory) { return DEFAULT_SYMBOL; } function _mint(address to, uint value) internal { totalSupply += value; balanceOf[to] += value; emit Transfer(address(0), to, value); } function _burn(address from, uint value) internal { balanceOf[from] -= value; totalSupply -= value; emit Transfer(from, address(0), value); } function _approve(address owner, address spender, uint value) private { allowance[owner][spender] = value; emit Approval(owner, spender, value); } function _transfer(address from, address to, uint value) private { balanceOf[from] -= value; balanceOf[to] += value; emit Transfer(from, to, value); } function approve(address spender, uint value) external returns (bool) { _approve(msg.sender, spender, value); return true; } function transfer(address to, uint value) external returns (bool) { _transfer(msg.sender, to, value); return true; } function transferFrom(address from, address to, uint value) external returns (bool) { if (allowance[from][msg.sender] != type(uint).max) { allowance[from][msg.sender] -= value; } _transfer(from, to, value); return true; } function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external { require(deadline >= block.timestamp, "TetuSwapERC20: EXPIRED"); bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR, keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, "TetuSwapERC20: INVALID_SIGNATURE"); _approve(owner, spender, value); } }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; /// @title Uniswap UQ112x112 solution https://github.com/Uniswap/v2-core/blob/master/contracts/libraries/UQ112x112.sol /// A library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) /// @dev range: [0, 2**112 - 1] /// resolution: 1 / 2**112 library UQ112x112 { uint224 constant Q112 = 2 ** 112; /// @dev Encode a uint112 as a UQ112x112 function encode(uint112 y) internal pure returns (uint224 z) { z = uint224(y) * Q112; // never overflows } /// @dev Divide a UQ112x112 by a uint112, returning a UQ112x112 function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) { z = x / uint224(y); } }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; /// @title Uniswap Math https://github.com/Uniswap/v2-core/blob/master/contracts/libraries/Math.sol /// A library for performing various math operations library Math { function min(uint x, uint y) internal pure returns (uint z) { z = x < y ? x : y; } /// @dev Babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint y) internal pure returns (uint z) { z = 0; if (y > 3) { z = y; uint x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "../interfaces/ITetuSwapPair.sol"; import "../interfaces/ITetuSwapFactory.sol"; /// @title UniswapV2Library https://github.com/Uniswap/v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol library TetuSwapLibrary { using SafeMath for uint; uint constant private _PRECISION = 10000; uint constant private _FEE = 2; /// @dev returns sorted token addresses, used to handle return values from pairs sorted in this order function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { require(tokenA != tokenB, "TSL: IDENTICAL_ADDRESSES"); (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0), "TSL: ZERO_ADDRESS"); } /// @dev use stored in factory pairs instead on the flay calculation /// we have more flexible system and can't use old function function pairFor(address factory, address tokenA, address tokenB) internal view returns (address pair) { return ITetuSwapFactory(factory).getPair(tokenA, tokenB); } /// @dev fetches and sorts the reserves for a pair function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) { (address token0,) = sortTokens(tokenA, tokenB); (uint reserve0, uint reserve1,) = ITetuSwapPair(pairFor(factory, tokenA, tokenB)).getReserves(); (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); } /// @dev given some amount of an asset and pair reserves, returns an equivalent amount of the other asset function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) { require(amountA > 0, "TSL: INSUFFICIENT_AMOUNT"); require(reserveA > 0 && reserveB > 0, "TSL: INSUFFICIENT_LIQUIDITY"); amountB = amountA.mul(reserveB) / reserveA; } /// @dev given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut, uint fee) internal pure returns (uint amountOut) { require(amountIn > 0, "TSL: INSUFFICIENT_INPUT_AMOUNT"); require(reserveIn > 0 && reserveOut > 0, "TSL: INSUFFICIENT_LIQUIDITY"); uint amountInWithFee = amountIn.mul(_PRECISION - fee); uint numerator = amountInWithFee.mul(reserveOut); uint denominator = reserveIn.mul(_PRECISION).add(amountInWithFee); amountOut = numerator / denominator; } /// @dev given an output amount of an asset and pair reserves, returns a required input amount of the other asset function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut, uint fee) internal pure returns (uint amountIn) { require(amountOut > 0, "TSL: INSUFFICIENT_OUTPUT_AMOUNT"); require(reserveIn > 0 && reserveOut > 0, "TSL: INSUFFICIENT_LIQUIDITY"); uint numerator = reserveIn.mul(amountOut).mul(_PRECISION); uint denominator = reserveOut.sub(amountOut).mul(_PRECISION - fee); amountIn = (numerator / denominator).add(1); } /// @dev performs chained getAmountOut calculations on any number of pairs function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) { require(path.length >= 2, "TSL: INVALID_PATH"); amounts = new uint[](path.length); amounts[0] = amountIn; for (uint i; i < path.length - 1; i++) { (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]); amounts[i + 1] = getAmountOut( amounts[i], reserveIn, reserveOut, ITetuSwapPair(pairFor(factory, path[i], path[i + 1])).fee() ); } } /// @dev performs chained getAmountIn calculations on any number of pairs function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) { require(path.length >= 2, "TSL: INVALID_PATH"); amounts = new uint[](path.length); amounts[amounts.length - 1] = amountOut; for (uint i = path.length - 1; i > 0; i--) { (uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i]); amounts[i - 1] = getAmountIn( amounts[i], reserveIn, reserveOut, ITetuSwapPair(pairFor(factory, path[i - 1], path[i])).fee() ); } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.4; interface IUniswapV2Callee { function uniswapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.4; interface IUniswapV2Factory { event PairCreated(address indexed token0, address indexed token1, address pair, uint); function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function feeTo() external view returns (address); function feeToSetter() external view returns (address); function createPair(address tokenA, address tokenB) external returns (address pair); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.4; interface IERC20Name { function name() external view returns (string memory); function symbol() external view returns (string memory); }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; interface ISmartVault { function setStrategy(address _strategy) external; function changeActivityStatus(bool _active) external; function changePpfsDecreaseAllowed(bool _value) external; function setLockPeriod(uint256 _value) external; function setLockPenalty(uint256 _value) external; function setToInvest(uint256 _value) external; function doHardWork() external; function rebalance() external; function disableLock() external; function notifyTargetRewardAmount(address _rewardToken, uint256 reward) external; function notifyRewardWithoutPeriodChange(address _rewardToken, uint256 reward) external; function deposit(uint256 amount) external; function depositAndInvest(uint256 amount) external; function depositFor(uint256 amount, address holder) external; function withdraw(uint256 numberOfShares) external; function exit() external; function getAllRewards() external; function getReward(address rt) external; function underlying() external view returns (address); function strategy() external view returns (address); function getRewardTokenIndex(address rt) external view returns (uint256); function getPricePerFullShare() external view returns (uint256); function underlyingUnit() external view returns (uint256); function duration() external view returns (uint256); function underlyingBalanceInVault() external view returns (uint256); function underlyingBalanceWithInvestment() external view returns (uint256); function underlyingBalanceWithInvestmentForHolder(address holder) external view returns (uint256); function availableToInvestOut() external view returns (uint256); function earned(address rt, address account) external view returns (uint256); function earnedWithBoost(address rt, address account) external view returns (uint256); function rewardPerToken(address rt) external view returns (uint256); function lastTimeRewardApplicable(address rt) external view returns (uint256); function rewardTokensLength() external view returns (uint256); function active() external view returns (bool); function rewardTokens() external view returns (address[] memory); function periodFinishForToken(address _rt) external view returns (uint256); function rewardRateForToken(address _rt) external view returns (uint256); function lastUpdateTimeForToken(address _rt) external view returns (uint256); function rewardPerTokenStoredForToken(address _rt) external view returns (uint256); function userRewardPerTokenPaidForToken(address _rt, address account) external view returns (uint256); function rewardsForToken(address _rt, address account) external view returns (uint256); function userLastWithdrawTs(address _user) external returns (uint256); function userLastDepositTs(address _user) external returns (uint256); function userBoostTs(address _user) external returns (uint256); function userLockTs(address _user) external returns (uint256); function addRewardToken(address rt) external; function removeRewardToken(address rt) external; function stop() external; function ppfsDecreaseAllowed() external view returns (bool); function lockPeriod() external view returns (uint256); function lockPenalty() external view returns (uint256); function toInvest() external view returns (uint256); function lockAllowed() external view returns (bool); }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; interface ITetuSwapPair { function balanceOfVaultUnderlying(address _token) external view returns (uint); function setFee(uint _fee) external; function setVaults(address _vault0, address _vault1) external; function setRewardRecipient(address _recipient) external; function claimAll() external; function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function rewardRecipient() external view returns (address); function fee() external view returns (uint); function token0() external view returns (address); function token1() external view returns (address); function vault0() external view returns (address); function vault1() 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 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, bytes calldata data) external; function sync() external; function initialize( address _token0, address _token1, uint _fee ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { return a + b; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b > 0, errorMessage); return a % b; } } }
// SPDX-License-Identifier: ISC /** * By using this software, you understand, acknowledge and accept that Tetu * and/or the underlying software are provided “as is” and “as available” * basis and without warranties or representations of any kind either expressed * or implied. Any use of this open source software released under the ISC * Internet Systems Consortium license is done at your own risk to the fullest * extent permissible pursuant to applicable law any and all liability as well * as all warranties, including any fitness for a particular purpose with respect * to Tetu and/or the underlying software and the use thereof are disclaimed. */ pragma solidity 0.8.4; interface ITetuSwapFactory { function getPair(address tokenA, address tokenB) external view returns (address pair); function allPairs(uint) external view returns (address pair); function allPairsLength() external view returns (uint); function createPair(address tokenA, address tokenB) external returns (address pair); function validPairs(address _pair) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 150 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"blockTs","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"FeeChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldRecipient","type":"address"},{"indexed":false,"internalType":"address","name":"newRecipient","type":"address"}],"name":"RewardRecipientChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1In","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0Out","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Out","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint112","name":"reserve0","type":"uint112"},{"indexed":false,"internalType":"uint112","name":"reserve1","type":"uint112"}],"name":"Sync","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vault0","type":"address"},{"indexed":false,"internalType":"address","name":"vault1","type":"address"}],"name":"VaultsChanged","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_LIQUIDITY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"balanceOfVaultUnderlying","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"burn","outputs":[{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"createdBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"createdTs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"},{"internalType":"uint256","name":"amountOutWithFee","type":"uint256"}],"name":"getFeeAmount","outputs":[{"internalType":"uint256","name":"amountFee","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint112","name":"_reserve0","type":"uint112"},{"internalType":"uint112","name":"_reserve1","type":"uint112"},{"internalType":"uint32","name":"_blockTimestampLast","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token0","type":"address"},{"internalType":"address","name":"_token1","type":"address"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[{"internalType":"uint256","name":"liquidity","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"price0CumulativeLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price1CumulativeLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRecipient","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"setRewardRecipient","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vault0","type":"address"},{"internalType":"address","name":"_vault1","type":"address"}],"name":"setVaults","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount0Out","type":"uint256"},{"internalType":"uint256","name":"amount1Out","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vault1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultReserve0","outputs":[{"internalType":"uint112","name":"","type":"uint112"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultReserve1","outputs":[{"internalType":"uint112","name":"","type":"uint112"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50604080518082018252600b81526a05465747553776170204c560ac1b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f918101919091527fb78cf64ac322bb8ec4cb80679b3778f97968af51fa1924a34ca2e65a7ba800ac918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6606082015246608082018190523060a08301529060c00160408051601f198184030181529190528051602090910120600355506001600555600680546001600160a01b03191633179055613ebe806101136000396000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c806385f8c25911610151578063d1058e59116100c3578063e521136f11610087578063e521136f146105a6578063ebbdfc00146105b9578063f070ba03146105c1578063f53f83ab146105ca578063ffa1ad74146105dd578063fff6cae91461060157600080fd5b8063d1058e5914610544578063d21220a71461054c578063d505accf1461055f578063dd62ed3e14610572578063ddca3f431461059d57600080fd5b8063a7af479611610115578063a7af4796146104f1578063a9059cbb14610504578063aaf5eb6814610517578063ba9a7a5614610520578063bc063e1a14610529578063c45a01551461053157600080fd5b806385f8c2591461048857806389afcb441461049b57806395d89b41146104c35780639bec62c9146104cb578063a1512a2b146104de57600080fd5b8063313ce567116101ea5780635a3d5493116101ae5780635a3d5493146103f957806362cecf801461040257806369fe0e2d146104225780636a6278421461043557806370a08231146104485780637ecebe001461046857600080fd5b8063313ce567146103b15780633644e515146103cb5780634593144c146103d45780634c451a6a146103dd5780635909c0d5146103f057600080fd5b80631794bb3c116102315780631794bb3c1461033a57806317f333401461034d57806318160ddd1461036057806323b872dd1461037757806330adf81f1461038a57600080fd5b8063022c0d9f1461026e57806306fdde03146102835780630902f1ac146102c3578063095ea7b3146102f75780630dfe16811461031a575b600080fd5b61028161027c366004613a44565b610609565b005b6102ad6040518060400160405280600b81526020016a05465747553776170204c560ac1b81525081565b6040516102ba9190613bf9565b60405180910390f35b6102cb610ae5565b604080516001600160701b03948516815293909216602084015263ffffffff16908201526060016102ba565b61030a610305366004613885565b610b0f565b60405190151581526020016102ba565b60085461032d906001600160a01b031681565b6040516102ba9190613b99565b6102816103483660046137d0565b610b25565b60075461032d906001600160a01b031681565b61036960005481565b6040519081526020016102ba565b61030a6103853660046137d0565b610d81565b6103697f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6103b9601281565b60405160ff90911681526020016102ba565b61036960035481565b61036960125481565b6102816103eb366004613798565b610dfc565b610369600d5481565b610369600e5481565b61040a6110cd565b6040516001600160701b0390911681526020016102ba565b610281610430366004613a14565b611153565b610369610443366004613760565b611203565b610369610456366004613760565b60016020526000908152604090205481565b610369610476366004613760565b60046020526000908152604090205481565b610369610496366004613ad5565b6115b7565b6104ae6104a9366004613760565b6115dc565b604080519283526020830191909152016102ba565b6102ad611bb3565b600b5461032d906001600160a01b031681565b600a5461032d906001600160a01b031681565b6103696104ff366004613760565b611c45565b61030a610512366004613885565b611e38565b61036961271081565b6103696103e881565b610369601e81565b60065461032d906001600160a01b031681565b610281611e45565b60095461032d906001600160a01b031681565b61028161056d366004613810565b611efe565b610369610580366004613798565b600260209081526000928352604080842090915290825290205481565b61036960105481565b6102816105b4366004613760565b612116565b61040a6121a9565b61036960115481565b6103696105d8366004613b00565b6121da565b6102ad604051806040016040528060058152602001640312e302e360dc1b81525081565b610281612236565b600260055414156106355760405162461bcd60e51b815260040161062c90613c56565b60405180910390fd5b6002600555841515806106485750600084115b6106945760405162461bcd60e51b815260206004820152601f60248201527f5453503a20496e73756666696369656e74206f757470757420616d6f756e7400604482015260640161062c565b60008061069f610ae5565b5091509150816001600160701b0316871080156106c45750806001600160701b031686105b6107105760405162461bcd60e51b815260206004820152601b60248201527f5453503a20496e73756666696369656e74206c69717569646974790000000000604482015260640161062c565b600061072f87846001600160701b0316846001600160701b03166115b7565b9050600061075089846001600160701b0316866001600160701b03166115b7565b6008546040516370a0823160e01b81529192506000916001600160a01b03909116906370a0823190610786903090600401613b99565b60206040518083038186803b15801561079e57600080fd5b505afa1580156107b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107d69190613a2c565b6009546040516370a0823160e01b81529192506000916001600160a01b03909116906370a082319061080c903090600401613b99565b60206040518083038186803b15801561082457600080fd5b505afa158015610838573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085c9190613a2c565b905083821015801561086e5750828110155b6108ba5760405162461bcd60e51b815260206004820152601e60248201527f5453503a20496e73756666696369656e7420696e70757420616d6f756e740000604482015260640161062c565b811561091f57600a5460405163b6b55f2560e01b8152600481018490526001600160a01b039091169063b6b55f2590602401600060405180830381600087803b15801561090657600080fd5b505af115801561091a573d6000803e3d6000fd5b505050505b801561098457600b5460405163b6b55f2560e01b8152600481018390526001600160a01b039091169063b6b55f2590602401600060405180830381600087803b15801561096b57600080fd5b505af115801561097f573d6000803e3d6000fd5b505050505b6000818311156109b3576109ac83886001600160701b0316886001600160701b03168e6121da565b90506109d4565b6109d182876001600160701b0316896001600160701b03168f6121da565b90505b6109e28c8c8c8c8c8661226d565b5060006109ed6121a9565b6001600160701b031690506000610a026110cd565b6001600160701b03169050866001600160701b0316886001600160701b0316610a2b9190613d3f565b610a358284613d3f565b1015610a745760405162461bcd60e51b815260206004820152600e60248201526d5453503a204b20746f6f206c6f7760901b604482015260640161062c565b5050610a7e612408565b60408051838152602081018390529081018c9052606081018b90526001600160a01b038a169033907fd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d8229060800160405180910390a350506001600555505050505050505050565b600c546001600160701b0380821692600160701b830490911691600160e01b900463ffffffff1690565b6000610b1c33848461264b565b50600192915050565b6006546001600160a01b03163314610b4f5760405162461bcd60e51b815260040161062c90613c2c565b601e811115610b945760405162461bcd60e51b81526020600482015260116024820152705453503a20546f6f20686967682066656560781b604482015260640161062c565b6008546001600160a01b031615610be85760405162461bcd60e51b81526020600482015260186024820152771514d40e88105b1c9958591e481a5b9a5d1a585b1a5e995960421b604482015260640161062c565b6009546001600160a01b031615610c3c5760405162461bcd60e51b81526020600482015260186024820152771514d40e88105b1c9958591e481a5b9a5d1a585b1a5e995960421b604482015260640161062c565b600880546001600160a01b038086166001600160a01b0319928316811790935560098054918616919092161790556010829055604080516395d89b4160e01b81529051610d5f92916395d89b41916004808301926000929190829003018186803b158015610ca957600080fd5b505afa158015610cbd573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610ce59190810190613984565b836001600160a01b03166395d89b416040518163ffffffff1660e01b815260040160006040518083038186803b158015610d1e57600080fd5b505afa158015610d32573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d5a9190810190613984565b6126ad565b8051610d7391600f916020909101906136c7565b505042601155505043601255565b6001600160a01b038316600090815260026020908152604080832033845290915281205460001914610de6576001600160a01b038416600090815260026020908152604080832033845290915281208054849290610de0908490613d5e565b90915550505b610df18484846126d9565b5060015b9392505050565b6006546001600160a01b03163314610e265760405162461bcd60e51b815260040161062c90613c2c565b60085460408051636f307dc360e01b815290516001600160a01b0392831692851691636f307dc3916004808301926020929190829003018186803b158015610e6d57600080fd5b505afa158015610e81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ea5919061377c565b6001600160a01b031614610efb5760405162461bcd60e51b815260206004820152601c60248201527f5453503a2057726f6e67207661756c743020756e6465726c79696e6700000000604482015260640161062c565b60095460408051636f307dc360e01b815290516001600160a01b0392831692841691636f307dc3916004808301926020929190829003018186803b158015610f4257600080fd5b505afa158015610f56573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7a919061377c565b6001600160a01b031614610fd05760405162461bcd60e51b815260206004820152601c60248201527f5453503a2057726f6e67207661756c743120756e6465726c79696e6700000000604482015260640161062c565b600a54610fe5906001600160a01b031661277a565b600b54610ffa906001600160a01b031661277a565b600a80546001600160a01b038085166001600160a01b031992831617909255600b805484841692169190911790556008546110399116836000196128f8565b600954611052906001600160a01b0316826000196128f8565b600a54611067906001600160a01b0316612a54565b50600b5461107d906001600160a01b0316612a54565b50600a54600b54604080516001600160a01b0393841681529290911660208301527f61e68e33253f2a551a18c535ab9b82eca5bcd1708100bc72a549595262fd8ac3910160405180910390a15050565b600b54604051638cb1d67f60e01b81526000916001600160a01b031690638cb1d67f906110fe903090600401613b99565b60206040518083038186803b15801561111657600080fd5b505afa15801561112a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114e9190613a2c565b905090565b6006546001600160a01b0316331461117d5760405162461bcd60e51b815260040161062c90613c2c565b601e8111156111c25760405162461bcd60e51b81526020600482015260116024820152705453503a20546f6f20686967682066656560781b604482015260640161062c565b60105460408051918252602082018390527f5fc463da23c1b063e66f9e352006a7fbe8db7223c455dc429e881a2dfe2f94f1910160405180910390a1601055565b6000600260055414156112285760405162461bcd60e51b815260040161062c90613c56565b6002600555600a546040516370a0823160e01b81526000916001600160a01b0316906370a082319061125e903090600401613b99565b60206040518083038186803b15801561127657600080fd5b505afa15801561128a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112ae9190613a2c565b600b546040516370a0823160e01b81529192506000916001600160a01b03909116906370a08231906112e4903090600401613b99565b60206040518083038186803b1580156112fc57600080fd5b505afa158015611310573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113349190613a2c565b600a5490915060009061134f906001600160a01b0316612a54565b600b5490915060009061136a906001600160a01b0316612a54565b600a546040516370a0823160e01b815291925060009186916001600160a01b0316906370a08231906113a0903090600401613b99565b60206040518083038186803b1580156113b857600080fd5b505afa1580156113cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f09190613a2c565b6113fa9190613d5e565b600b546040516370a0823160e01b815291925060009186916001600160a01b0316906370a0823190611430903090600401613b99565b60206040518083038186803b15801561144857600080fd5b505afa15801561145c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114809190613a2c565b61148a9190613d5e565b600054909150806114c8576103e86114aa6114a58486613d3f565b612bab565b6114b49190613d5e565b97506114c360006103e8612c1b565b6114fd565b6114fa876114d68386613d3f565b6114e09190613cfc565b876114eb8486613d3f565b6114f59190613cfc565b612ca4565b97505b600088116115585760405162461bcd60e51b815260206004820152602260248201527f5453503a20496e73756666696369656e74206c6971756964697479206d696e74604482015261195960f21b606482015260840161062c565b6115628989612c1b565b61156a612408565b604080518681526020810186905233917f4c209b5fc8ad50758f13e2e1088ba56a560dff690a1c6fef26394f4c03821c4f910160405180910390a250506001600555509395945050505050565b6000836115c657506000610df5565b6115d4848484601054612cba565b949350505050565b600080600260055414156116025760405162461bcd60e51b815260040161062c90613c56565b6002600555600a546040516370a0823160e01b81526000916001600160a01b0316906370a0823190611638903090600401613b99565b60206040518083038186803b15801561165057600080fd5b505afa158015611664573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116889190613a2c565b600b546040516370a0823160e01b81529192506000916001600160a01b03909116906370a08231906116be903090600401613b99565b60206040518083038186803b1580156116d657600080fd5b505afa1580156116ea573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170e9190613a2c565b3060009081526001602052604081205481549293509161172e8584613d3f565b6117389190613cfc565b905060008054848461174a9190613d3f565b6117549190613cfc565b90506000821180156117665750600081115b6117bd5760405162461bcd60e51b815260206004820152602260248201527f5453503a20496e73756666696369656e74206c6971756964697479206275726e604482015261195960f21b606482015260840161062c565b6117c73084612dbe565b600a546040516370a0823160e01b81526001600160a01b03909116906370a08231906117f7903090600401613b99565b60206040518083038186803b15801561180f57600080fd5b505afa158015611823573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118479190613a2c565b8211156118965760405162461bcd60e51b815260206004820152601a60248201527f5453503a20496e73756666696369656e74207368617265732030000000000000604482015260640161062c565b600b546040516370a0823160e01b81526001600160a01b03909116906370a08231906118c6903090600401613b99565b60206040518083038186803b1580156118de57600080fd5b505afa1580156118f2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119169190613a2c565b8111156119655760405162461bcd60e51b815260206004820152601a60248201527f5453503a20496e73756666696369656e74207368617265732031000000000000604482015260640161062c565b600a54604051632e1a7d4d60e01b8152600481018490526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b1580156119ab57600080fd5b505af11580156119bf573d6000803e3d6000fd5b5050600b54604051632e1a7d4d60e01b8152600481018590526001600160a01b039091169250632e1a7d4d9150602401600060405180830381600087803b158015611a0957600080fd5b505af1158015611a1d573d6000803e3d6000fd5b50506008546040516370a0823160e01b81526001600160a01b0390911692506370a082319150611a51903090600401613b99565b60206040518083038186803b158015611a6957600080fd5b505afa158015611a7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa19190613a2c565b6009546040516370a0823160e01b81529198506001600160a01b0316906370a0823190611ad2903090600401613b99565b60206040518083038186803b158015611aea57600080fd5b505afa158015611afe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b229190613a2c565b600854909650611b3c906001600160a01b03168989612e41565b600954611b53906001600160a01b03168988612e41565b611b5b612408565b60408051888152602081018890526001600160a01b038a169133917fdccd412f0b1252819cb1fd330b93224ca42612892bb3f4f789976e6d81936496910160405180910390a350505050506001600581905550915091565b6060600f8054611bc290613dca565b80601f0160208091040260200160405190810160405280929190818152602001828054611bee90613dca565b8015611c3b5780601f10611c1057610100808354040283529160200191611c3b565b820191906000526020600020905b815481529060010190602001808311611c1e57829003601f168201915b5050505050905090565b600a5460408051636f307dc360e01b815290516000926001600160a01b031691636f307dc3916004808301926020929190829003018186803b158015611c8a57600080fd5b505afa158015611c9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cc2919061377c565b6001600160a01b0316826001600160a01b03161415611d6157600a54604051638cb1d67f60e01b81526001600160a01b0390911690638cb1d67f90611d0b903090600401613b99565b60206040518083038186803b158015611d2357600080fd5b505afa158015611d37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d5b9190613a2c565b92915050565b600b60009054906101000a90046001600160a01b03166001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b158015611daf57600080fd5b505afa158015611dc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611de7919061377c565b6001600160a01b0316826001600160a01b03161415611e3057600b54604051638cb1d67f60e01b81526001600160a01b0390911690638cb1d67f90611d0b903090600401613b99565b506000919050565b6000610b1c3384846126d9565b6007546001600160a01b03163314611e9f5760405162461bcd60e51b815260206004820152601d60248201527f5453503a204f6e6c7920726563697069656e742063616e20636c61696d000000604482015260640161062c565b600a54611eb4906001600160a01b0316612e71565b600b54611ec9906001600160a01b0316612e71565b6040514281527f7a355715549cfe7c1cba26304350343fbddc4b4f72d3ce3e7c27117dd20b5cb89060200160405180910390a1565b42841015611f475760405162461bcd60e51b815260206004820152601660248201527515195d1d54ddd85c115490cc8c0e881156141254915160521b604482015260640161062c565b6003546001600160a01b038816600090815260046020526040812080549192917f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918b918b918b919087611f9a83613dff565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810187905260e0016040516020818303038152906040528051906020012060405160200161201392919061190160f01b81526002810192909252602282015260420190565b60408051601f198184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa15801561207e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906120b45750886001600160a01b0316816001600160a01b0316145b6121005760405162461bcd60e51b815260206004820181905260248201527f546574755377617045524332303a20494e56414c49445f5349474e4154555245604482015260640161062c565b61210b89898961264b565b505050505050505050565b6006546001600160a01b031633146121405760405162461bcd60e51b815260040161062c90613c2c565b600754604080516001600160a01b03928316815291831660208301527fae1f37ae5efbfb242e3b24245f203971d97a432a097847314eb005bed5d00f4a910160405180910390a1600780546001600160a01b0319166001600160a01b0392909216919091179055565b600a54604051638cb1d67f60e01b81526000916001600160a01b031690638cb1d67f906110fe903090600401613b99565b6000846121e9575060006115d4565b60006121f88686866000613175565b905082811161220b5760009150506115d4565b600a6122178483613d5e565b612222906009613d3f565b61222c9190613cfc565b9695505050505050565b600260055414156122595760405162461bcd60e51b815260040161062c90613c56565b6002600555612266612408565b6001600555565b6008546009546001600160a01b039182169190811690861682148015906122a65750806001600160a01b0316866001600160a01b031614155b6122e45760405162461bcd60e51b815260206004820152600f60248201526e5453503a20496e76616c696420746f60881b604482015260640161062c565b871561233d57600a54612309906001600160a01b0316612304858b613cbe565b613274565b61231d6001600160a01b038316878a612e41565b821561233d5760075461233d906001600160a01b03848116911685612e41565b861561239157600b5461235d906001600160a01b0316612304858a613cbe565b6123716001600160a01b0382168789612e41565b821561239157600754612391906001600160a01b03838116911685612e41565b83156123fe576040516304347a1760e21b81526001600160a01b038716906310d1e85c906123cb9033908c908c908b908b90600401613bad565b600060405180830381600087803b1580156123e557600080fd5b505af11580156123f9573d6000803e3d6000fd5b505050505b5050505050505050565b60006124126121a9565b6001600160701b0316905060006124276110cd565b6001600160701b039081169150821180159061244a57506001600160701b038111155b6124865760405162461bcd60e51b815260206004820152600d60248201526c5453503a204f564552464c4f5760981b604482015260640161062c565b600061249764010000000042613e1a565b600c549091506000906124b790600160e01b900463ffffffff1683613d75565b905060008163ffffffff161180156124d95750600c546001600160701b031615155b80156124f65750600c54600160701b90046001600160701b031615155b156125b557600c5463ffffffff821690612537906001600160701b038082169161252891600160701b909104166134a8565b6001600160e01b0316906134c1565b6001600160e01b031661254a9190613d3f565b600d600082825461255b9190613cbe565b9091555050600c5463ffffffff82169061258b906001600160701b03600160701b820481169161252891166134a8565b6001600160e01b031661259e9190613d3f565b600e60008282546125af9190613cbe565b90915550505b600c805463ffffffff8416600160e01b026001600160e01b036001600160701b03878116600160701b9081026001600160e01b03199095168a83161794909417918216831794859055604080519382169282169290921783529290930490911660208201527f1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1910160405180910390a150505050565b6001600160a01b0383811660008181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b606082826040516020016126c2929190613b4d565b604051602081830303815290604052905092915050565b6001600160a01b03831660009081526001602052604081208054839290612701908490613d5e565b90915550506001600160a01b0382166000908152600160205260408120805483929061272e908490613cbe565b92505081905550816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516126a091815260200190565b6001600160a01b03811661278b5750565b6040516370a0823160e01b81526000906001600160a01b038316906370a08231906127ba903090600401613b99565b60206040518083038186803b1580156127d257600080fd5b505afa1580156127e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280a9190613a2c565b9050801561286d57604051632e1a7d4d60e01b8152600481018290526001600160a01b03831690632e1a7d4d90602401600060405180830381600087803b15801561285457600080fd5b505af1158015612868573d6000803e3d6000fd5b505050505b6128f4826000846001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b1580156128ac57600080fd5b505afa1580156128c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128e4919061377c565b6001600160a01b031691906128f8565b5050565b8015806129815750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b15801561294757600080fd5b505afa15801561295b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061297f9190613a2c565b155b6129ec5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606482015260840161062c565b6040516001600160a01b038316602482015260448101829052612a4f90849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526134d6565b505050565b600080826001600160a01b0316636f307dc36040518163ffffffff1660e01b815260040160206040518083038186803b158015612a9057600080fd5b505afa158015612aa4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ac8919061377c565b6001600160a01b03166370a08231306040518263ffffffff1660e01b8152600401612af39190613b99565b60206040518083038186803b158015612b0b57600080fd5b505afa158015612b1f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b439190613a2c565b90508015611d5b5760405163b6b55f2560e01b8152600481018290526001600160a01b0384169063b6b55f2590602401600060405180830381600087803b158015612b8d57600080fd5b505af1158015612ba1573d6000803e3d6000fd5b5050505092915050565b60006003821115612c0c5750806000612bc5600283613cfc565b612bd0906001613cbe565b90505b81811015612c0657905080600281612beb8186613cfc565b612bf59190613cbe565b612bff9190613cfc565b9050612bd3565b50919050565b8115612c16575060015b919050565b80600080828254612c2c9190613cbe565b90915550506001600160a01b03821660009081526001602052604081208054839290612c59908490613cbe565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020015b60405180910390a35050565b6000818310612cb35781610df5565b5090919050565b6000808511612d0b5760405162461bcd60e51b815260206004820152601f60248201527f54534c3a20494e53554646494349454e545f4f55545055545f414d4f554e5400604482015260640161062c565b600084118015612d1b5750600083115b612d675760405162461bcd60e51b815260206004820152601b60248201527f54534c3a20494e53554646494349454e545f4c49515549444954590000000000604482015260640161062c565b6000612d7f612710612d7987896135a8565b906135a8565b90506000612d9c612d9285612710613d5e565b612d79878a6135b4565b9050612db36001612dad8385613cfc565b906135c0565b979650505050505050565b6001600160a01b03821660009081526001602052604081208054839290612de6908490613d5e565b9250508190555080600080828254612dfe9190613d5e565b90915550506040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001612c98565b6040516001600160a01b038316602482015260448101829052612a4f90849063a9059cbb60e01b90606401612a18565b6001600160a01b038116612eb95760405162461bcd60e51b815260206004820152600f60248201526e1514d40e8816995c9bc81d985d5b1d608a1b604482015260640161062c565b8060005b816001600160a01b031663bf199e626040518163ffffffff1660e01b815260040160206040518083038186803b158015612ef657600080fd5b505afa158015612f0a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f2e9190613a2c565b811015612a4f576000826001600160a01b031663c2b18aa06040518163ffffffff1660e01b815260040160006040518083038186803b158015612f7057600080fd5b505afa158015612f84573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612fac91908101906138b0565b8281518110612fcb57634e487b7160e01b600052603260045260246000fd5b602002602001015190506000816001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016130039190613b99565b60206040518083038186803b15801561301b57600080fd5b505afa15801561302f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130539190613a2c565b604051630c00007b60e41b81529091506001600160a01b0385169063c00007b090613082908590600401613b99565b600060405180830381600087803b15801561309c57600080fd5b505af11580156130b0573d6000803e3d6000fd5b50505050600081836001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016130e39190613b99565b60206040518083038186803b1580156130fb57600080fd5b505afa15801561310f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131339190613a2c565b61313d9190613d5e565b9050801561315f5760075461315f906001600160a01b03858116911683612e41565b505050808061316d90613dff565b915050612ebd565b60008085116131c65760405162461bcd60e51b815260206004820152601e60248201527f54534c3a20494e53554646494349454e545f494e5055545f414d4f554e540000604482015260640161062c565b6000841180156131d65750600083115b6132225760405162461bcd60e51b815260206004820152601b60248201527f54534c3a20494e53554646494349454e545f4c49515549444954590000000000604482015260640161062c565b600061323a61323384612710613d5e565b87906135a8565b9050600061324882866135a8565b9050600061325c83612dad896127106135a8565b90506132688183613cfc565b98975050505050505050565b6040516370a0823160e01b815282906000906001600160a01b038316906370a08231906132a5903090600401613b99565b60206040518083038186803b1580156132bd57600080fd5b505afa1580156132d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132f59190613a2c565b90506000826001600160a01b03166377c7b8fc6040518163ffffffff1660e01b815260040160206040518083038186803b15801561333257600080fd5b505afa158015613346573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061336a9190613a2c565b836001600160a01b03166353ceb01c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156133a357600080fd5b505afa1580156133b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133db9190613a2c565b6133e59086613d3f565b6133ef9190613cfc565b90506134056133ff826001613cbe565b83612ca4565b9050818111156134525760405162461bcd60e51b81526020600482015260186024820152775453503a20496e73756666696369656e742073686172657360401b604482015260640161062c565b604051632e1a7d4d60e01b8152600481018290526001600160a01b03841690632e1a7d4d90602401600060405180830381600087803b15801561349457600080fd5b505af115801561210b573d6000803e3d6000fd5b6000611d5b600160701b6001600160701b038416613d10565b6000610df56001600160701b03831684613cd6565b600061352b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166135cc9092919063ffffffff16565b805190915015612a4f57808060200190518101906135499190613964565b612a4f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161062c565b6000610df58284613d3f565b6000610df58284613d5e565b6000610df58284613cbe565b60606115d4848460008585843b6136255760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161062c565b600080866001600160a01b031685876040516136419190613b31565b60006040518083038185875af1925050503d806000811461367e576040519150601f19603f3d011682016040523d82523d6000602084013e613683565b606091505b5091509150612db38282866060831561369d575081610df5565b8251156136ad5782518084602001fd5b8160405162461bcd60e51b815260040161062c9190613bf9565b8280546136d390613dca565b90600052602060002090601f0160209004810192826136f5576000855561373b565b82601f1061370e57805160ff191683800117855561373b565b8280016001018555821561373b579182015b8281111561373b578251825591602001919060010190613720565b5061374792915061374b565b5090565b5b80821115613747576000815560010161374c565b600060208284031215613771578081fd5b8135610df581613e70565b60006020828403121561378d578081fd5b8151610df581613e70565b600080604083850312156137aa578081fd5b82356137b581613e70565b915060208301356137c581613e70565b809150509250929050565b6000806000606084860312156137e4578081fd5b83356137ef81613e70565b925060208401356137ff81613e70565b929592945050506040919091013590565b600080600080600080600060e0888a03121561382a578283fd5b873561383581613e70565b9650602088013561384581613e70565b95506040880135945060608801359350608088013560ff81168114613868578384fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215613897578182fd5b82356138a281613e70565b946020939093013593505050565b600060208083850312156138c2578182fd5b825167ffffffffffffffff808211156138d9578384fd5b818501915085601f8301126138ec578384fd5b8151818111156138fe576138fe613e5a565b8060051b915061390f848301613c8d565b8181528481019084860184860187018a1015613929578788fd5b8795505b83861015613957578051945061394285613e70565b8483526001959095019491860191860161392d565b5098975050505050505050565b600060208284031215613975578081fd5b81518015158114610df5578182fd5b600060208284031215613995578081fd5b815167ffffffffffffffff808211156139ac578283fd5b818401915084601f8301126139bf578283fd5b8151818111156139d1576139d1613e5a565b6139e4601f8201601f1916602001613c8d565b91508082528560208285010111156139fa578384fd5b613a0b816020840160208601613d9a565b50949350505050565b600060208284031215613a25578081fd5b5035919050565b600060208284031215613a3d578081fd5b5051919050565b600080600080600060808688031215613a5b578081fd5b85359450602086013593506040860135613a7481613e70565b9250606086013567ffffffffffffffff80821115613a90578283fd5b818801915088601f830112613aa3578283fd5b813581811115613ab1578384fd5b896020828501011115613ac2578384fd5b9699959850939650602001949392505050565b600080600060608486031215613ae9578081fd5b505081359360208301359350604090920135919050565b60008060008060808587031215613b15578182fd5b5050823594602084013594506040840135936060013592509050565b60008251613b43818460208701613d9a565b9190910192915050565b63544c505f60e01b815260008351613b6c816004850160208801613d9a565b605f60f81b6004918401918201528351613b8d816005840160208801613d9a565b01600501949350505050565b6001600160a01b0391909116815260200190565b60018060a01b038616815284602082015283604082015260806060820152816080820152818360a0830137600081830160a090810191909152601f909201601f19160101949350505050565b6020815260008251806020840152613c18816040850160208701613d9a565b601f01601f19169190910160400192915050565b60208082526010908201526f5453503a204e6f7420666163746f727960801b604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b604051601f8201601f1916810167ffffffffffffffff81118282101715613cb657613cb6613e5a565b604052919050565b60008219821115613cd157613cd1613e2e565b500190565b60006001600160e01b0383811680613cf057613cf0613e44565b92169190910492915050565b600082613d0b57613d0b613e44565b500490565b60006001600160e01b0382811684821681151582840482111615613d3657613d36613e2e565b02949350505050565b6000816000190483118215151615613d5957613d59613e2e565b500290565b600082821015613d7057613d70613e2e565b500390565b600063ffffffff83811690831681811015613d9257613d92613e2e565b039392505050565b60005b83811015613db5578181015183820152602001613d9d565b83811115613dc4576000848401525b50505050565b600181811c90821680613dde57607f821691505b60208210811415612c0657634e487b7160e01b600052602260045260246000fd5b6000600019821415613e1357613e13613e2e565b5060010190565b600082613e2957613e29613e44565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114613e8557600080fd5b5056fea2646970667358221220acc799683694a385b19304a1a3f480aee197367f6f20af9c612d605bdc94182464736f6c63430008040033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.