Contract Overview
Balance:
0 MOVR
MOVR Value:
$0.00
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Contract Name:
SwapRouter
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; import "./interfaces/ISwap.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; contract SwapRouter { using SafeERC20 for IERC20; function convert( ISwap fromPool, ISwap toPool, uint256 amount, uint256 minToMint, uint256 deadline ) external returns (uint256) { uint256 fromPoolLength = fromPool.getNumberOfTokens(); uint256 toPoolLength = toPool.getNumberOfTokens(); require(address(fromPool) != address(toPool), "fromPool = toPool"); require(fromPoolLength == toPoolLength, "poolTokensLengthMissmatch"); IERC20 fromToken = fromPool.getLpToken(); IERC20 toToken = toPool.getLpToken(); uint256[] memory min_amounts = new uint256[](fromPoolLength); // validate token for (uint8 i = 0; i < fromPoolLength; i++) { IERC20 coin = fromPool.getToken(i); toPool.getTokenIndex(address(coin)); } fromToken.transferFrom(msg.sender, address(this), amount); fromToken.safeIncreaseAllowance(address(fromPool), amount); fromPool.removeLiquidity(amount, min_amounts, deadline); uint256[] memory meta_amounts = new uint256[](toPoolLength); for (uint8 i = 0; i < toPoolLength; i++) { IERC20 coin = toPool.getToken(i); uint256 addBalance = coin.balanceOf(address(this)); coin.safeIncreaseAllowance(address(toPool), addBalance); meta_amounts[i] = addBalance; } toPool.addLiquidity(meta_amounts, minToMint, deadline); uint256 lpAmount = toToken.balanceOf(address(this)); toToken.transfer(msg.sender, lpAmount); return lpAmount; } function addLiquidity( ISwap pool, ISwap basePool, uint256[] memory meta_amounts, uint256[] memory base_amounts, uint256 minToMint, uint256 deadline ) external returns (uint256) { IERC20 token = IERC20(pool.getLpToken()); IERC20 base_lp = IERC20(basePool.getLpToken()); require(base_amounts.length == basePool.getNumberOfTokens(), "invalidBaseAmountsLength"); require(meta_amounts.length == pool.getNumberOfTokens(), "invalidMetaAmountsLength"); bool deposit_base = false; for (uint8 i = 0; i < base_amounts.length; i++) { uint256 amount = base_amounts[i]; if (amount > 0) { deposit_base = true; IERC20 coin = basePool.getToken(i); uint256 transferred = transferIn(coin, msg.sender, amount); coin.safeIncreaseAllowance(address(basePool), transferred); base_amounts[i] = transferred; } } uint256 base_lp_received; if (deposit_base) { base_lp_received = basePool.addLiquidity(base_amounts, 0, deadline); } for (uint8 i = 0; i < meta_amounts.length; i++) { IERC20 coin = pool.getToken(i); uint256 transferred; if (address(coin) == address(base_lp)) { transferred = base_lp_received; } else if (meta_amounts[i] > 0) { transferred = transferIn(coin, msg.sender, meta_amounts[i]); } meta_amounts[i] = transferred; if (transferred > 0) { coin.safeIncreaseAllowance(address(pool), transferred); } } uint256 base_lp_prior = base_lp.balanceOf(address(this)); pool.addLiquidity(meta_amounts, minToMint, deadline); if (deposit_base) { require((base_lp.balanceOf(address(this)) + base_lp_received) == base_lp_prior, "invalidBasePool"); } uint256 lpAmount = token.balanceOf(address(this)); token.transfer(msg.sender, lpAmount); return lpAmount; } function removeLiquidity( ISwap pool, ISwap basePool, uint256 _amount, uint256[] calldata min_amounts_meta, uint256[] calldata min_amounts_base, uint256 deadline ) external returns (uint256[] memory amounts, uint256[] memory base_amounts) { IERC20 token = pool.getLpToken(); IERC20 baseToken = basePool.getLpToken(); token.transferFrom(msg.sender, address(this), _amount); token.safeIncreaseAllowance(address(pool), _amount); pool.removeLiquidity(_amount, min_amounts_meta, deadline); uint256 _base_amount = baseToken.balanceOf(address(this)); baseToken.safeIncreaseAllowance(address(basePool), _base_amount); basePool.removeLiquidity(_base_amount, min_amounts_base, deadline); // Transfer all coins out amounts = new uint256[](pool.getNumberOfTokens()); for (uint8 i = 0; i < pool.getNumberOfTokens(); i++) { IERC20 coin = pool.getToken(i); amounts[i] = coin.balanceOf(address(this)); if (amounts[i] > 0) { coin.safeTransfer(msg.sender, amounts[i]); } } base_amounts = new uint256[](basePool.getNumberOfTokens()); for (uint8 i = 0; i < basePool.getNumberOfTokens(); i++) { IERC20 coin = basePool.getToken(i); base_amounts[i] = coin.balanceOf(address(this)); if (base_amounts[i] > 0) { coin.safeTransfer(msg.sender, base_amounts[i]); } } } function removeBaseLiquidityOneToken( ISwap pool, ISwap basePool, uint256 _token_amount, uint8 i, uint256 _min_amount, uint256 deadline ) external returns (uint256) { IERC20 token = pool.getLpToken(); IERC20 baseToken = basePool.getLpToken(); uint8 baseTokenIndex = pool.getTokenIndex(address(baseToken)); token.transferFrom(msg.sender, address(this), _token_amount); token.approve(address(pool), _token_amount); pool.removeLiquidityOneToken(_token_amount, baseTokenIndex, 0, deadline); uint256 _base_amount = baseToken.balanceOf(address(this)); baseToken.approve(address(basePool), _base_amount); basePool.removeLiquidityOneToken(_base_amount, i, _min_amount, deadline); IERC20 coin = basePool.getToken(i); uint256 coin_amount = coin.balanceOf(address(this)); coin.safeTransfer(msg.sender, coin_amount); return coin_amount; } function swapFromBase( ISwap pool, ISwap basePool, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline ) external returns (uint256) { IERC20 baseToken = basePool.getLpToken(); uint8 baseTokenIndex = pool.getTokenIndex(address(baseToken)); uint256[] memory base_amounts = new uint256[](basePool.getNumberOfTokens()); base_amounts[tokenIndexFrom] = dx; IERC20 coin = basePool.getToken(tokenIndexFrom); coin.safeTransferFrom(msg.sender, address(this), dx); coin.safeIncreaseAllowance(address(basePool), dx); uint256 baseLpAmount = basePool.addLiquidity(base_amounts, 0, deadline); if (baseTokenIndex != tokenIndexTo) { baseToken.safeIncreaseAllowance(address(pool), baseLpAmount); pool.swap(baseTokenIndex, tokenIndexTo, baseLpAmount, minDy, deadline); } IERC20 coinTo = pool.getToken(tokenIndexTo); uint256 amountOut = coinTo.balanceOf(address(this)); coinTo.safeTransfer(msg.sender, amountOut); return amountOut; } function swapToBase( ISwap pool, ISwap basePool, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline ) external returns (uint256) { IERC20 baseToken = basePool.getLpToken(); uint8 baseTokenIndex = pool.getTokenIndex(address(baseToken)); IERC20 coin = pool.getToken(tokenIndexFrom); coin.safeTransferFrom(msg.sender, address(this), dx); uint256 tokenLPAmount = dx; if (baseTokenIndex != tokenIndexFrom) { coin.safeIncreaseAllowance(address(pool), dx); tokenLPAmount = pool.swap(tokenIndexFrom, baseTokenIndex, dx, 0, deadline); } baseToken.safeIncreaseAllowance(address(basePool), tokenLPAmount); basePool.removeLiquidityOneToken(tokenLPAmount, tokenIndexTo, minDy, deadline); IERC20 coinTo = basePool.getToken(tokenIndexTo); uint256 amountOut = coinTo.balanceOf(address(this)); coinTo.safeTransfer(msg.sender, amountOut); return amountOut; } // =========== VIEW =========== function calculateConvert( ISwap fromPool, ISwap toPool, uint256 amount ) external view returns (uint256) { uint256 fromPoolLength = fromPool.getNumberOfTokens(); uint256[] memory amounts = fromPool.calculateRemoveLiquidity(amount); uint256[] memory meta_amounts = new uint256[](fromPoolLength); for (uint8 i = 0; i < fromPoolLength; i++) { IERC20 fromCoin = fromPool.getToken(i); uint256 toCoinIndex = toPool.getTokenIndex(address(fromCoin)); meta_amounts[toCoinIndex] = amounts[i]; } return toPool.calculateTokenAmount(meta_amounts, true); } function calculateTokenAmount( ISwap pool, ISwap basePool, uint256[] memory meta_amounts, uint256[] memory base_amounts, bool is_deposit ) external view returns (uint256) { IERC20 baseToken = basePool.getLpToken(); uint8 baseTokenIndex = pool.getTokenIndex(address(baseToken)); uint256 _base_tokens = basePool.calculateTokenAmount(base_amounts, is_deposit); meta_amounts[baseTokenIndex] = meta_amounts[baseTokenIndex] + _base_tokens; return pool.calculateTokenAmount(meta_amounts, is_deposit); } function calculateRemoveLiquidity( ISwap pool, ISwap basePool, uint256 amount ) external view returns (uint256[] memory meta_amounts, uint256[] memory base_amounts) { IERC20 baseToken = basePool.getLpToken(); uint8 baseTokenIndex = pool.getTokenIndex(address(baseToken)); meta_amounts = pool.calculateRemoveLiquidity(amount); uint256 lpAmount = meta_amounts[baseTokenIndex]; meta_amounts[baseTokenIndex] = 0; base_amounts = basePool.calculateRemoveLiquidity(lpAmount); } function calculateRemoveBaseLiquidityOneToken( ISwap pool, ISwap basePool, uint256 _token_amount, uint8 iBase ) external view returns (uint256 availableTokenAmount) { IERC20 baseToken = basePool.getLpToken(); uint8 baseTokenIndex = pool.getTokenIndex(address(baseToken)); uint256 _base_tokens = pool.calculateRemoveLiquidityOneToken(_token_amount, baseTokenIndex); availableTokenAmount = basePool.calculateRemoveLiquidityOneToken(_base_tokens, iBase); } function calculateSwapFromBase( ISwap pool, ISwap basePool, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx ) external view returns (uint256) { IERC20 baseToken = basePool.getLpToken(); uint8 baseTokenIndex = pool.getTokenIndex(address(baseToken)); uint256[] memory base_amounts = new uint256[](basePool.getNumberOfTokens()); base_amounts[tokenIndexFrom] = dx; uint256 baseLpAmount = basePool.calculateTokenAmount(base_amounts, true); if (baseTokenIndex == tokenIndexTo) { return baseLpAmount; } return pool.calculateSwap(baseTokenIndex, tokenIndexTo, baseLpAmount); } function calculateSwapToBase( ISwap pool, ISwap basePool, uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx ) external view returns (uint256) { IERC20 baseToken = basePool.getLpToken(); uint8 baseTokenIndex = pool.getTokenIndex(address(baseToken)); uint256 tokenLPAmount = dx; if (baseTokenIndex != tokenIndexFrom) { tokenLPAmount = pool.calculateSwap(tokenIndexFrom, baseTokenIndex, dx); } return basePool.calculateRemoveLiquidityOneToken(tokenLPAmount, tokenIndexTo); } function transferIn( IERC20 token, address from, uint256 amount ) internal returns (uint256 transferred) { uint256 prior_balance = token.balanceOf(address(this)); token.safeTransferFrom(from, address(this), amount); transferred = token.balanceOf(address(this)) - prior_balance; } }
// SPDX-License-Identifier: MIT pragma solidity 0.6.12; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; interface ISwap { // pool data view functions function getA() external view returns (uint256); function getToken(uint8 index) external view returns (IERC20); function getTokenIndex(address tokenAddress) external view returns (uint8); function getTokenBalance(uint8 index) external view returns (uint256); function getVirtualPrice() external view returns (uint256); function getNumberOfTokens() external view returns (uint256); function getLpToken() external view returns (IERC20); // min return calculation functions function calculateSwap( uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx ) external view returns (uint256); function calculateTokenAmount(uint256[] calldata amounts, bool deposit) external view returns (uint256); function calculateRemoveLiquidity(uint256 amount) external view returns (uint256[] memory); function calculateRemoveLiquidityOneToken( uint256 tokenAmount, uint8 tokenIndex ) external view returns (uint256 availableTokenAmount); // state modifying functions function initialize( IERC20[] memory pooledTokens, uint8[] memory decimals, string memory lpTokenName, string memory lpTokenSymbol, uint256 a, uint256 fee, uint256 adminFee, address lpTokenTargetAddress ) external; function swap( uint8 tokenIndexFrom, uint8 tokenIndexTo, uint256 dx, uint256 minDy, uint256 deadline ) external returns (uint256); function addLiquidity( uint256[] calldata amounts, uint256 minToMint, uint256 deadline ) external returns (uint256); function removeLiquidity( uint256 amount, uint256[] calldata minAmounts, uint256 deadline ) external returns (uint256[] memory); function removeLiquidityOneToken( uint256 tokenAmount, uint8 tokenIndex, uint256 minAmount, uint256 deadline ) external returns (uint256); function removeLiquidityImbalance( uint256[] calldata amounts, uint256 maxBurnAmount, uint256 deadline ) external returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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.6.0 <0.8.0; import "./IERC20.sol"; import "../../math/SafeMath.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 SafeMath for uint256; 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' // solhint-disable-next-line max-line-length 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).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _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 // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ 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) { 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) { 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) { // 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) { 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) { 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) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @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) { require(b <= a, "SafeMath: subtraction overflow"); 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) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @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. 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) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); 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) { require(b > 0, "SafeMath: modulo by zero"); 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) { 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. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * 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) { 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) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <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; // solhint-disable-next-line no-inline-assembly 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"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (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"); // solhint-disable-next-line avoid-low-level-calls (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"); // solhint-disable-next-line avoid-low-level-calls (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"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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 // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "optimizer": { "enabled": true, "runs": 999999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
[{"inputs":[{"internalType":"contract ISwap","name":"pool","type":"address"},{"internalType":"contract ISwap","name":"basePool","type":"address"},{"internalType":"uint256[]","name":"meta_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"base_amounts","type":"uint256[]"},{"internalType":"uint256","name":"minToMint","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISwap","name":"fromPool","type":"address"},{"internalType":"contract ISwap","name":"toPool","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculateConvert","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISwap","name":"pool","type":"address"},{"internalType":"contract ISwap","name":"basePool","type":"address"},{"internalType":"uint256","name":"_token_amount","type":"uint256"},{"internalType":"uint8","name":"iBase","type":"uint8"}],"name":"calculateRemoveBaseLiquidityOneToken","outputs":[{"internalType":"uint256","name":"availableTokenAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISwap","name":"pool","type":"address"},{"internalType":"contract ISwap","name":"basePool","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"calculateRemoveLiquidity","outputs":[{"internalType":"uint256[]","name":"meta_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"base_amounts","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISwap","name":"pool","type":"address"},{"internalType":"contract ISwap","name":"basePool","type":"address"},{"internalType":"uint8","name":"tokenIndexFrom","type":"uint8"},{"internalType":"uint8","name":"tokenIndexTo","type":"uint8"},{"internalType":"uint256","name":"dx","type":"uint256"}],"name":"calculateSwapFromBase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISwap","name":"pool","type":"address"},{"internalType":"contract ISwap","name":"basePool","type":"address"},{"internalType":"uint8","name":"tokenIndexFrom","type":"uint8"},{"internalType":"uint8","name":"tokenIndexTo","type":"uint8"},{"internalType":"uint256","name":"dx","type":"uint256"}],"name":"calculateSwapToBase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISwap","name":"pool","type":"address"},{"internalType":"contract ISwap","name":"basePool","type":"address"},{"internalType":"uint256[]","name":"meta_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"base_amounts","type":"uint256[]"},{"internalType":"bool","name":"is_deposit","type":"bool"}],"name":"calculateTokenAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISwap","name":"fromPool","type":"address"},{"internalType":"contract ISwap","name":"toPool","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minToMint","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"convert","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISwap","name":"pool","type":"address"},{"internalType":"contract ISwap","name":"basePool","type":"address"},{"internalType":"uint256","name":"_token_amount","type":"uint256"},{"internalType":"uint8","name":"i","type":"uint8"},{"internalType":"uint256","name":"_min_amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeBaseLiquidityOneToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISwap","name":"pool","type":"address"},{"internalType":"contract ISwap","name":"basePool","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256[]","name":"min_amounts_meta","type":"uint256[]"},{"internalType":"uint256[]","name":"min_amounts_base","type":"uint256[]"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"base_amounts","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISwap","name":"pool","type":"address"},{"internalType":"contract ISwap","name":"basePool","type":"address"},{"internalType":"uint8","name":"tokenIndexFrom","type":"uint8"},{"internalType":"uint8","name":"tokenIndexTo","type":"uint8"},{"internalType":"uint256","name":"dx","type":"uint256"},{"internalType":"uint256","name":"minDy","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapFromBase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISwap","name":"pool","type":"address"},{"internalType":"contract ISwap","name":"basePool","type":"address"},{"internalType":"uint8","name":"tokenIndexFrom","type":"uint8"},{"internalType":"uint8","name":"tokenIndexTo","type":"uint8"},{"internalType":"uint256","name":"dx","type":"uint256"},{"internalType":"uint256","name":"minDy","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapToBase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061559e806100206000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c8063643abb86116100815780638a311c571161005b5780638a311c57146106ee578063998cae4714610744578063ff9693221461079c576100d4565b8063643abb861461050d57806377269e2914610550578063797018211461069f576100d4565b80633214b8c9116100b25780633214b8c91461040857806338c789731461045e57806354681c41146104c0576100d4565b80630c8b2216146100d95780630d6307eb146101b557806324a5bf2114610319575b600080fd5b61011c600480360360608110156100ef57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356107fe565b604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b83811015610160578181015183820152602001610148565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561019f578181015183820152602001610187565b5050505090500194505050505060405180910390f35b610307600480360360c08110156101cb57600080fd5b73ffffffffffffffffffffffffffffffffffffffff823581169260208101359091169181019060608101604082013564010000000081111561020c57600080fd5b82018360208201111561021e57600080fd5b8035906020019184602083028401116401000000008311171561024057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561029057600080fd5b8201836020820111156102a257600080fd5b803590602001918460208302840111640100000000831117156102c457600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505082359350505060200135610bee565b60408051918252519081900360200190f35b61011c600480360360c081101561032f57600080fd5b73ffffffffffffffffffffffffffffffffffffffff82358116926020810135909116916040820135919081019060808101606082013564010000000081111561037757600080fd5b82018360208201111561038957600080fd5b803590602001918460208302840111640100000000831117156103ab57600080fd5b9193909290916020810190356401000000008111156103c957600080fd5b8201836020820111156103db57600080fd5b803590602001918460208302840111640100000000831117156103fd57600080fd5b9193509150356115ef565b610307600480360360a081101561041e57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060ff60408201358116916060810135909116906080013561210b565b610307600480360360e081101561047457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060ff604082013581169160608101359091169060808101359060a08101359060c00135612376565b610307600480360360808110156104d657600080fd5b50803573ffffffffffffffffffffffffffffffffffffffff908116916020810135909116906040810135906060013560ff1661295b565b6103076004803603606081101561052357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135612bcc565b610307600480360360a081101561056657600080fd5b73ffffffffffffffffffffffffffffffffffffffff82358116926020810135909116918101906060810160408201356401000000008111156105a757600080fd5b8201836020820111156105b957600080fd5b803590602001918460208302840111640100000000831117156105db57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561062b57600080fd5b82018360208201111561063d57600080fd5b8035906020019184602083028401116401000000008311171561065f57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550505050351515905061303e565b610307600480360360a08110156106b557600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020810135909116906040810135906060810135906080013561330c565b610307600480360360a081101561070457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060ff604082013581169160608101359091169060800135613da8565b610307600480360360c081101561075a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060408101359060ff6060820135169060808101359060a00135614151565b610307600480360360e08110156107b257600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060ff604082013581169160608101359091169060808101359060a08101359060c0013561486c565b60608060008473ffffffffffffffffffffffffffffffffffffffff16638214f5a46040518163ffffffff1660e01b815260040160206040518083038186803b15801561084957600080fd5b505afa15801561085d573d6000803e3d6000fd5b505050506040513d602081101561087357600080fd5b5051604080517f66c0bd2400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80841660048301529151929350600092918916916366c0bd2491602480820192602092909190829003018186803b1580156108eb57600080fd5b505afa1580156108ff573d6000803e3d6000fd5b505050506040513d602081101561091557600080fd5b5051604080517ff2fad2b600000000000000000000000000000000000000000000000000000000815260048101889052905191925073ffffffffffffffffffffffffffffffffffffffff89169163f2fad2b691602480820192600092909190829003018186803b15801561098857600080fd5b505afa15801561099c573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405260208110156109e357600080fd5b8101908080516040519392919084640100000000821115610a0357600080fd5b908301906020820185811115610a1857600080fd5b8251866020820283011164010000000082111715610a3557600080fd5b82525081516020918201928201910280838360005b83811015610a62578181015183820152602001610a4a565b5050505090500160405250505093506000848260ff1681518110610a8257fe5b602002602001015190506000858360ff1681518110610a9d57fe5b6020026020010181815250508673ffffffffffffffffffffffffffffffffffffffff1663f2fad2b6826040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b158015610afa57600080fd5b505afa158015610b0e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526020811015610b5557600080fd5b8101908080516040519392919084640100000000821115610b7557600080fd5b908301906020820185811115610b8a57600080fd5b8251866020820283011164010000000082111715610ba757600080fd5b82525081516020918201928201910280838360005b83811015610bd4578181015183820152602001610bbc565b505050509050016040525050509350505050935093915050565b6000808773ffffffffffffffffffffffffffffffffffffffff16638214f5a46040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3757600080fd5b505afa158015610c4b573d6000803e3d6000fd5b505050506040513d6020811015610c6157600080fd5b5051604080517f8214f5a4000000000000000000000000000000000000000000000000000000008152905191925060009173ffffffffffffffffffffffffffffffffffffffff8a1691638214f5a4916004808301926020929190829003018186803b158015610ccf57600080fd5b505afa158015610ce3573d6000803e3d6000fd5b505050506040513d6020811015610cf957600080fd5b5051604080517fefeecb51000000000000000000000000000000000000000000000000000000008152905191925073ffffffffffffffffffffffffffffffffffffffff8a169163efeecb5191600480820192602092909190829003018186803b158015610d6557600080fd5b505afa158015610d79573d6000803e3d6000fd5b505050506040513d6020811015610d8f57600080fd5b5051865114610dff57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f696e76616c696442617365416d6f756e74734c656e6774680000000000000000604482015290519081900360640190fd5b8873ffffffffffffffffffffffffffffffffffffffff1663efeecb516040518163ffffffff1660e01b815260040160206040518083038186803b158015610e4557600080fd5b505afa158015610e59573d6000803e3d6000fd5b505050506040513d6020811015610e6f57600080fd5b5051875114610edf57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f696e76616c69644d657461416d6f756e74734c656e6774680000000000000000604482015290519081900360640190fd5b6000805b87518160ff161015610ff3576000888260ff1681518110610f0057fe5b602002602001015190506000811115610fea576001925060008b73ffffffffffffffffffffffffffffffffffffffff166382b86600846040518263ffffffff1660e01b8152600401808260ff16815260200191505060206040518083038186803b158015610f6d57600080fd5b505afa158015610f81573d6000803e3d6000fd5b505050506040513d6020811015610f9757600080fd5b505190506000610fa8823385614d64565b9050610fcb73ffffffffffffffffffffffffffffffffffffffff83168e83614ebc565b808b8560ff1681518110610fdb57fe5b60200260200101818152505050505b50600101610ee3565b50600081156110cd578973ffffffffffffffffffffffffffffffffffffffff16634d49e87d896000896040518463ffffffff1660e01b81526004018080602001848152602001838152602001828103825285818151815260200191508051906020019060200280838360005b8381101561107757818101518382015260200161105f565b50505050905001945050505050602060405180830381600087803b15801561109e57600080fd5b505af11580156110b2573d6000803e3d6000fd5b505050506040513d60208110156110c857600080fd5b505190505b60005b89518160ff1610156112195760008c73ffffffffffffffffffffffffffffffffffffffff166382b86600836040518263ffffffff1660e01b8152600401808260ff16815260200191505060206040518083038186803b15801561113257600080fd5b505afa158015611146573d6000803e3d6000fd5b505050506040513d602081101561115c57600080fd5b50519050600073ffffffffffffffffffffffffffffffffffffffff808316908716141561118a5750826111cd565b60008c8460ff168151811061119b57fe5b602002602001015111156111cd576111ca82338e8660ff16815181106111bd57fe5b6020026020010151614d64565b90505b808c8460ff16815181106111dd57fe5b6020908102919091010152801561120f5761120f73ffffffffffffffffffffffffffffffffffffffff83168f83614ebc565b50506001016110d0565b5060008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561128357600080fd5b505afa158015611297573d6000803e3d6000fd5b505050506040513d60208110156112ad57600080fd5b50516040517f4d49e87d000000000000000000000000000000000000000000000000000000008152602481018a9052604481018990526060600482019081528c5160648301528c5192935073ffffffffffffffffffffffffffffffffffffffff8f1692634d49e87d928e928d928d9282916084909101906020878101910280838360005b83811015611349578181015183820152602001611331565b50505050905001945050505050602060405180830381600087803b15801561137057600080fd5b505af1158015611384573d6000803e3d6000fd5b505050506040513d602081101561139a57600080fd5b505082156114a45780828573ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561140b57600080fd5b505afa15801561141f573d6000803e3d6000fd5b505050506040513d602081101561143557600080fd5b505101146114a457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f696e76616c696442617365506f6f6c0000000000000000000000000000000000604482015290519081900360640190fd5b60008573ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561150d57600080fd5b505afa158015611521573d6000803e3d6000fd5b505050506040513d602081101561153757600080fd5b5051604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815233600482015260248101839052905191925073ffffffffffffffffffffffffffffffffffffffff88169163a9059cbb916044808201926020929091908290030181600087803b1580156115b257600080fd5b505af11580156115c6573d6000803e3d6000fd5b505050506040513d60208110156115dc57600080fd5b50909d9c50505050505050505050505050565b60608060008a73ffffffffffffffffffffffffffffffffffffffff16638214f5a46040518163ffffffff1660e01b815260040160206040518083038186803b15801561163a57600080fd5b505afa15801561164e573d6000803e3d6000fd5b505050506040513d602081101561166457600080fd5b5051604080517f8214f5a4000000000000000000000000000000000000000000000000000000008152905191925060009173ffffffffffffffffffffffffffffffffffffffff8d1691638214f5a4916004808301926020929190829003018186803b1580156116d257600080fd5b505afa1580156116e6573d6000803e3d6000fd5b505050506040513d60208110156116fc57600080fd5b5051604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018d9052905191925073ffffffffffffffffffffffffffffffffffffffff8416916323b872dd916064808201926020929091908290030181600087803b15801561177d57600080fd5b505af1158015611791573d6000803e3d6000fd5b505050506040513d60208110156117a757600080fd5b506117cb905073ffffffffffffffffffffffffffffffffffffffff83168d8c614ebc565b8b73ffffffffffffffffffffffffffffffffffffffff166331cd52b08b8b8b896040518563ffffffff1660e01b815260040180858152602001806020018381526020018281038252858582818152602001925060200280828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b15801561185d57600080fd5b505af1158015611871573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405260208110156118b857600080fd5b81019080805160405193929190846401000000008211156118d857600080fd5b9083019060208201858111156118ed57600080fd5b825186602082028301116401000000008211171561190a57600080fd5b82525081516020918201928201910280838360005b8381101561193757818101518382015260200161191f565b505050509050016040525050505060008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156119ae57600080fd5b505afa1580156119c2573d6000803e3d6000fd5b505050506040513d60208110156119d857600080fd5b505190506119fd73ffffffffffffffffffffffffffffffffffffffff83168d83614ebc565b8b73ffffffffffffffffffffffffffffffffffffffff166331cd52b0828a8a8a6040518563ffffffff1660e01b815260040180858152602001806020018381526020018281038252858582818152602001925060200280828437600081840152601f19601f82011690508083019250505095505050505050600060405180830381600087803b158015611a8f57600080fd5b505af1158015611aa3573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526020811015611aea57600080fd5b8101908080516040519392919084640100000000821115611b0a57600080fd5b908301906020820185811115611b1f57600080fd5b8251866020820283011164010000000082111715611b3c57600080fd5b82525081516020918201928201910280838360005b83811015611b69578181015183820152602001611b51565b50505050905001604052505050508c73ffffffffffffffffffffffffffffffffffffffff1663efeecb516040518163ffffffff1660e01b815260040160206040518083038186803b158015611bbd57600080fd5b505afa158015611bd1573d6000803e3d6000fd5b505050506040513d6020811015611be757600080fd5b505167ffffffffffffffff81118015611bff57600080fd5b50604051908082528060200260200182016040528015611c29578160200160208202803683370190505b50945060005b8d73ffffffffffffffffffffffffffffffffffffffff1663efeecb516040518163ffffffff1660e01b815260040160206040518083038186803b158015611c7557600080fd5b505afa158015611c89573d6000803e3d6000fd5b505050506040513d6020811015611c9f57600080fd5b505160ff82161015611e4f5760008e73ffffffffffffffffffffffffffffffffffffffff166382b86600836040518263ffffffff1660e01b8152600401808260ff16815260200191505060206040518083038186803b158015611d0157600080fd5b505afa158015611d15573d6000803e3d6000fd5b505050506040513d6020811015611d2b57600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191925073ffffffffffffffffffffffffffffffffffffffff8316916370a0823191602480820192602092909190829003018186803b158015611d9d57600080fd5b505afa158015611db1573d6000803e3d6000fd5b505050506040513d6020811015611dc757600080fd5b50518751889060ff8516908110611dda57fe5b6020026020010181815250506000878360ff1681518110611df757fe5b60200260200101511115611e4657611e4633888460ff1681518110611e1857fe5b60200260200101518373ffffffffffffffffffffffffffffffffffffffff1661500f9092919063ffffffff16565b50600101611c2f565b508b73ffffffffffffffffffffffffffffffffffffffff1663efeecb516040518163ffffffff1660e01b815260040160206040518083038186803b158015611e9657600080fd5b505afa158015611eaa573d6000803e3d6000fd5b505050506040513d6020811015611ec057600080fd5b505167ffffffffffffffff81118015611ed857600080fd5b50604051908082528060200260200182016040528015611f02578160200160208202803683370190505b50935060005b8c73ffffffffffffffffffffffffffffffffffffffff1663efeecb516040518163ffffffff1660e01b815260040160206040518083038186803b158015611f4e57600080fd5b505afa158015611f62573d6000803e3d6000fd5b505050506040513d6020811015611f7857600080fd5b505160ff821610156120fa5760008d73ffffffffffffffffffffffffffffffffffffffff166382b86600836040518263ffffffff1660e01b8152600401808260ff16815260200191505060206040518083038186803b158015611fda57600080fd5b505afa158015611fee573d6000803e3d6000fd5b505050506040513d602081101561200457600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191925073ffffffffffffffffffffffffffffffffffffffff8316916370a0823191602480820192602092909190829003018186803b15801561207657600080fd5b505afa15801561208a573d6000803e3d6000fd5b505050506040513d60208110156120a057600080fd5b50518651879060ff85169081106120b357fe5b6020026020010181815250506000868360ff16815181106120d057fe5b602002602001015111156120f1576120f133878460ff1681518110611e1857fe5b50600101611f08565b505050509850989650505050505050565b6000808573ffffffffffffffffffffffffffffffffffffffff16638214f5a46040518163ffffffff1660e01b815260040160206040518083038186803b15801561215457600080fd5b505afa158015612168573d6000803e3d6000fd5b505050506040513d602081101561217e57600080fd5b5051604080517f66c0bd2400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80841660048301529151929350600092918a16916366c0bd2491602480820192602092909190829003018186803b1580156121f657600080fd5b505afa15801561220a573d6000803e3d6000fd5b505050506040513d602081101561222057600080fd5b505190508360ff808316908816146122df57604080517fa95b089f00000000000000000000000000000000000000000000000000000000815260ff808a1660048301528416602482015260448101879052905173ffffffffffffffffffffffffffffffffffffffff8b169163a95b089f916064808301926020929190829003018186803b1580156122b057600080fd5b505afa1580156122c4573d6000803e3d6000fd5b505050506040513d60208110156122da57600080fd5b505190505b8773ffffffffffffffffffffffffffffffffffffffff1663342a87a182886040518363ffffffff1660e01b8152600401808381526020018260ff1681526020019250505060206040518083038186803b15801561233b57600080fd5b505afa15801561234f573d6000803e3d6000fd5b505050506040513d602081101561236557600080fd5b505193505050505b95945050505050565b6000808773ffffffffffffffffffffffffffffffffffffffff16638214f5a46040518163ffffffff1660e01b815260040160206040518083038186803b1580156123bf57600080fd5b505afa1580156123d3573d6000803e3d6000fd5b505050506040513d60208110156123e957600080fd5b5051604080517f66c0bd2400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80841660048301529151929350600092918c16916366c0bd2491602480820192602092909190829003018186803b15801561246157600080fd5b505afa158015612475573d6000803e3d6000fd5b505050506040513d602081101561248b57600080fd5b5051604080517fefeecb51000000000000000000000000000000000000000000000000000000008152905191925060609173ffffffffffffffffffffffffffffffffffffffff8c169163efeecb51916004808301926020929190829003018186803b1580156124f957600080fd5b505afa15801561250d573d6000803e3d6000fd5b505050506040513d602081101561252357600080fd5b505167ffffffffffffffff8111801561253b57600080fd5b50604051908082528060200260200182016040528015612565578160200160208202803683370190505b50905086818a60ff168151811061257857fe5b60200260200101818152505060008a73ffffffffffffffffffffffffffffffffffffffff166382b866008b6040518263ffffffff1660e01b8152600401808260ff16815260200191505060206040518083038186803b1580156125da57600080fd5b505afa1580156125ee573d6000803e3d6000fd5b505050506040513d602081101561260457600080fd5b5051905061262a73ffffffffffffffffffffffffffffffffffffffff821633308b6150a1565b61264b73ffffffffffffffffffffffffffffffffffffffff82168c8a614ebc565b60008b73ffffffffffffffffffffffffffffffffffffffff16634d49e87d8460008a6040518463ffffffff1660e01b81526004018080602001848152602001838152602001828103825285818151815260200191508051906020019060200280838360005b838110156126c85781810151838201526020016126b0565b50505050905001945050505050602060405180830381600087803b1580156126ef57600080fd5b505af1158015612703573d6000803e3d6000fd5b505050506040513d602081101561271957600080fd5b5051905060ff848116908b16146128065761274b73ffffffffffffffffffffffffffffffffffffffff86168e83614ebc565b604080517f9169558600000000000000000000000000000000000000000000000000000000815260ff80871660048301528c16602482015260448101839052606481018a905260848101899052905173ffffffffffffffffffffffffffffffffffffffff8f169163916955869160a48083019260209291908290030181600087803b1580156127d957600080fd5b505af11580156127ed573d6000803e3d6000fd5b505050506040513d602081101561280357600080fd5b50505b60008d73ffffffffffffffffffffffffffffffffffffffff166382b866008c6040518263ffffffff1660e01b8152600401808260ff16815260200191505060206040518083038186803b15801561285c57600080fd5b505afa158015612870573d6000803e3d6000fd5b505050506040513d602081101561288657600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191925060009173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b1580156128fa57600080fd5b505afa15801561290e573d6000803e3d6000fd5b505050506040513d602081101561292457600080fd5b5051905061294973ffffffffffffffffffffffffffffffffffffffff8316338361500f565b9e9d5050505050505050505050505050565b6000808473ffffffffffffffffffffffffffffffffffffffff16638214f5a46040518163ffffffff1660e01b815260040160206040518083038186803b1580156129a457600080fd5b505afa1580156129b8573d6000803e3d6000fd5b505050506040513d60208110156129ce57600080fd5b5051604080517f66c0bd2400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80841660048301529151929350600092918916916366c0bd2491602480820192602092909190829003018186803b158015612a4657600080fd5b505afa158015612a5a573d6000803e3d6000fd5b505050506040513d6020811015612a7057600080fd5b5051604080517f342a87a10000000000000000000000000000000000000000000000000000000081526004810188905260ff83166024820152905191925060009173ffffffffffffffffffffffffffffffffffffffff8a169163342a87a1916044808301926020929190829003018186803b158015612aee57600080fd5b505afa158015612b02573d6000803e3d6000fd5b505050506040513d6020811015612b1857600080fd5b5051604080517f342a87a10000000000000000000000000000000000000000000000000000000081526004810183905260ff88166024820152905191925073ffffffffffffffffffffffffffffffffffffffff89169163342a87a191604480820192602092909190829003018186803b158015612b9457600080fd5b505afa158015612ba8573d6000803e3d6000fd5b505050506040513d6020811015612bbe57600080fd5b505198975050505050505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663efeecb516040518163ffffffff1660e01b815260040160206040518083038186803b158015612c1557600080fd5b505afa158015612c29573d6000803e3d6000fd5b505050506040513d6020811015612c3f57600080fd5b5051604080517ff2fad2b600000000000000000000000000000000000000000000000000000000815260048101869052905191925060609173ffffffffffffffffffffffffffffffffffffffff88169163f2fad2b6916024808301926000929190829003018186803b158015612cb457600080fd5b505afa158015612cc8573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526020811015612d0f57600080fd5b8101908080516040519392919084640100000000821115612d2f57600080fd5b908301906020820185811115612d4457600080fd5b8251866020820283011164010000000082111715612d6157600080fd5b82525081516020918201928201910280838360005b83811015612d8e578181015183820152602001612d76565b50505050905001604052505050905060608267ffffffffffffffff81118015612db657600080fd5b50604051908082528060200260200182016040528015612de0578160200160208202803683370190505b50905060005b838160ff161015612f545760008873ffffffffffffffffffffffffffffffffffffffff166382b86600836040518263ffffffff1660e01b8152600401808260ff16815260200191505060206040518083038186803b158015612e4757600080fd5b505afa158015612e5b573d6000803e3d6000fd5b505050506040513d6020811015612e7157600080fd5b5051604080517f66c0bd2400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80841660048301529151929350600092918b16916366c0bd2491602480820192602092909190829003018186803b158015612ee957600080fd5b505afa158015612efd573d6000803e3d6000fd5b505050506040513d6020811015612f1357600080fd5b5051855160ff918216925086918516908110612f2b57fe5b6020026020010151848281518110612f3f57fe5b60209081029190910101525050600101612de6565b50604080517fe6ab28060000000000000000000000000000000000000000000000000000000081526001602482018190526004820192835283516044830152835173ffffffffffffffffffffffffffffffffffffffff8a169363e6ab2806938693928291606401906020808701910280838360005b83811015612fe1578181015183820152602001612fc9565b50505050905001935050505060206040518083038186803b15801561300557600080fd5b505afa158015613019573d6000803e3d6000fd5b505050506040513d602081101561302f57600080fd5b505193505050505b9392505050565b6000808573ffffffffffffffffffffffffffffffffffffffff16638214f5a46040518163ffffffff1660e01b815260040160206040518083038186803b15801561308757600080fd5b505afa15801561309b573d6000803e3d6000fd5b505050506040513d60208110156130b157600080fd5b5051604080517f66c0bd2400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80841660048301529151929350600092918a16916366c0bd2491602480820192602092909190829003018186803b15801561312957600080fd5b505afa15801561313d573d6000803e3d6000fd5b505050506040513d602081101561315357600080fd5b5051604080517fe6ab280600000000000000000000000000000000000000000000000000000000815286151560248201526004810191825287516044820152875192935060009273ffffffffffffffffffffffffffffffffffffffff8b169263e6ab2806928a928a92918291606490910190602086810191028083838c5b838110156131e95781810151838201526020016131d1565b50505050905001935050505060206040518083038186803b15801561320d57600080fd5b505afa158015613221573d6000803e3d6000fd5b505050506040513d602081101561323757600080fd5b505187519091508190889060ff851690811061324f57fe5b602002602001015101878360ff168151811061326757fe5b6020026020010181815250508873ffffffffffffffffffffffffffffffffffffffff1663e6ab280688876040518363ffffffff1660e01b815260040180806020018315158152602001828103825284818151815260200191508051906020019060200280838360005b838110156132e85781810151838201526020016132d0565b50505050905001935050505060206040518083038186803b15801561233b57600080fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1663efeecb516040518163ffffffff1660e01b815260040160206040518083038186803b15801561335557600080fd5b505afa158015613369573d6000803e3d6000fd5b505050506040513d602081101561337f57600080fd5b5051604080517fefeecb51000000000000000000000000000000000000000000000000000000008152905191925060009173ffffffffffffffffffffffffffffffffffffffff89169163efeecb51916004808301926020929190829003018186803b1580156133ed57600080fd5b505afa158015613401573d6000803e3d6000fd5b505050506040513d602081101561341757600080fd5b5051905073ffffffffffffffffffffffffffffffffffffffff88811690881614156134a357604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f66726f6d506f6f6c203d20746f506f6f6c000000000000000000000000000000604482015290519081900360640190fd5b80821461351157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f706f6f6c546f6b656e734c656e6774684d6973736d6174636800000000000000604482015290519081900360640190fd5b60008873ffffffffffffffffffffffffffffffffffffffff16638214f5a46040518163ffffffff1660e01b815260040160206040518083038186803b15801561355957600080fd5b505afa15801561356d573d6000803e3d6000fd5b505050506040513d602081101561358357600080fd5b5051604080517f8214f5a4000000000000000000000000000000000000000000000000000000008152905191925060009173ffffffffffffffffffffffffffffffffffffffff8b1691638214f5a4916004808301926020929190829003018186803b1580156135f157600080fd5b505afa158015613605573d6000803e3d6000fd5b505050506040513d602081101561361b57600080fd5b5051905060608467ffffffffffffffff8111801561363857600080fd5b50604051908082528060200260200182016040528015613662578160200160208202803683370190505b50905060005b858160ff16101561379d5760008c73ffffffffffffffffffffffffffffffffffffffff166382b86600836040518263ffffffff1660e01b8152600401808260ff16815260200191505060206040518083038186803b1580156136c957600080fd5b505afa1580156136dd573d6000803e3d6000fd5b505050506040513d60208110156136f357600080fd5b5051604080517f66c0bd2400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80841660048301529151929350908e16916366c0bd2491602480820192602092909190829003018186803b15801561376857600080fd5b505afa15801561377c573d6000803e3d6000fd5b505050506040513d602081101561379257600080fd5b505050600101613668565b50604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018b9052905173ffffffffffffffffffffffffffffffffffffffff8516916323b872dd9160648083019260209291908290030181600087803b15801561381957600080fd5b505af115801561382d573d6000803e3d6000fd5b505050506040513d602081101561384357600080fd5b50613867905073ffffffffffffffffffffffffffffffffffffffff84168c8b614ebc565b6040517f31cd52b0000000000000000000000000000000000000000000000000000000008152600481018a81526044820189905260606024830190815283516064840152835173ffffffffffffffffffffffffffffffffffffffff8f16936331cd52b0938e9387938e93608401906020808701910280838360005b838110156138fa5781810151838201526020016138e2565b50505050905001945050505050600060405180830381600087803b15801561392157600080fd5b505af1158015613935573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052602081101561397c57600080fd5b810190808051604051939291908464010000000082111561399c57600080fd5b9083019060208201858111156139b157600080fd5b82518660208202830111640100000000821117156139ce57600080fd5b82525081516020918201928201910280838360005b838110156139fb5781810151838201526020016139e3565b505050509050016040525050505060608467ffffffffffffffff81118015613a2257600080fd5b50604051908082528060200260200182016040528015613a4c578160200160208202803683370190505b50905060005b858160ff161015613bc55760008c73ffffffffffffffffffffffffffffffffffffffff166382b86600836040518263ffffffff1660e01b8152600401808260ff16815260200191505060206040518083038186803b158015613ab357600080fd5b505afa158015613ac7573d6000803e3d6000fd5b505050506040513d6020811015613add57600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191925060009173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015613b5157600080fd5b505afa158015613b65573d6000803e3d6000fd5b505050506040513d6020811015613b7b57600080fd5b50519050613ba073ffffffffffffffffffffffffffffffffffffffff83168f83614ebc565b80848460ff1681518110613bb057fe5b60209081029190910101525050600101613a52565b508a73ffffffffffffffffffffffffffffffffffffffff16634d49e87d828b8b6040518463ffffffff1660e01b81526004018080602001848152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015613c40578181015183820152602001613c28565b50505050905001945050505050602060405180830381600087803b158015613c6757600080fd5b505af1158015613c7b573d6000803e3d6000fd5b505050506040513d6020811015613c9157600080fd5b5050604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905160009173ffffffffffffffffffffffffffffffffffffffff8616916370a0823191602480820192602092909190829003018186803b158015613d0357600080fd5b505afa158015613d17573d6000803e3d6000fd5b505050506040513d6020811015613d2d57600080fd5b5051604080517fa9059cbb00000000000000000000000000000000000000000000000000000000815233600482015260248101839052905191925073ffffffffffffffffffffffffffffffffffffffff86169163a9059cbb916044808201926020929091908290030181600087803b1580156115b257600080fd5b6000808573ffffffffffffffffffffffffffffffffffffffff16638214f5a46040518163ffffffff1660e01b815260040160206040518083038186803b158015613df157600080fd5b505afa158015613e05573d6000803e3d6000fd5b505050506040513d6020811015613e1b57600080fd5b5051604080517f66c0bd2400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80841660048301529151929350600092918a16916366c0bd2491602480820192602092909190829003018186803b158015613e9357600080fd5b505afa158015613ea7573d6000803e3d6000fd5b505050506040513d6020811015613ebd57600080fd5b5051604080517fefeecb51000000000000000000000000000000000000000000000000000000008152905191925060609173ffffffffffffffffffffffffffffffffffffffff8a169163efeecb51916004808301926020929190829003018186803b158015613f2b57600080fd5b505afa158015613f3f573d6000803e3d6000fd5b505050506040513d6020811015613f5557600080fd5b505167ffffffffffffffff81118015613f6d57600080fd5b50604051908082528060200260200182016040528015613f97578160200160208202803683370190505b50905084818860ff1681518110613faa57fe5b60200260200101818152505060008873ffffffffffffffffffffffffffffffffffffffff1663e6ab28068360016040518363ffffffff1660e01b815260040180806020018315158152602001828103825284818151815260200191508051906020019060200280838360005b8381101561402e578181015183820152602001614016565b50505050905001935050505060206040518083038186803b15801561405257600080fd5b505afa158015614066573d6000803e3d6000fd5b505050506040513d602081101561407c57600080fd5b5051905060ff838116908816141561409957935061236d92505050565b604080517fa95b089f00000000000000000000000000000000000000000000000000000000815260ff80861660048301528916602482015260448101839052905173ffffffffffffffffffffffffffffffffffffffff8c169163a95b089f916064808301926020929190829003018186803b15801561411757600080fd5b505afa15801561412b573d6000803e3d6000fd5b505050506040513d602081101561414157600080fd5b50519a9950505050505050505050565b6000808773ffffffffffffffffffffffffffffffffffffffff16638214f5a46040518163ffffffff1660e01b815260040160206040518083038186803b15801561419a57600080fd5b505afa1580156141ae573d6000803e3d6000fd5b505050506040513d60208110156141c457600080fd5b5051604080517f8214f5a4000000000000000000000000000000000000000000000000000000008152905191925060009173ffffffffffffffffffffffffffffffffffffffff8a1691638214f5a4916004808301926020929190829003018186803b15801561423257600080fd5b505afa158015614246573d6000803e3d6000fd5b505050506040513d602081101561425c57600080fd5b5051604080517f66c0bd2400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80841660048301529151929350600092918c16916366c0bd2491602480820192602092909190829003018186803b1580156142d457600080fd5b505afa1580156142e8573d6000803e3d6000fd5b505050506040513d60208110156142fe57600080fd5b5051604080517f23b872dd000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018b9052905191925073ffffffffffffffffffffffffffffffffffffffff8516916323b872dd916064808201926020929091908290030181600087803b15801561437f57600080fd5b505af1158015614393573d6000803e3d6000fd5b505050506040513d60208110156143a957600080fd5b5050604080517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8c81166004830152602482018b905291519185169163095ea7b3916044808201926020929091908290030181600087803b15801561442457600080fd5b505af1158015614438573d6000803e3d6000fd5b505050506040513d602081101561444e57600080fd5b5050604080517f3e3a1560000000000000000000000000000000000000000000000000000000008152600481018a905260ff8316602482015260006044820181905260648201889052915173ffffffffffffffffffffffffffffffffffffffff8d1692633e3a156092608480820193602093909283900390910190829087803b1580156144da57600080fd5b505af11580156144ee573d6000803e3d6000fd5b505050506040513d602081101561450457600080fd5b5050604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905160009173ffffffffffffffffffffffffffffffffffffffff8516916370a0823191602480820192602092909190829003018186803b15801561457657600080fd5b505afa15801561458a573d6000803e3d6000fd5b505050506040513d60208110156145a057600080fd5b5051604080517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8d811660048301526024820184905291519293509085169163095ea7b3916044808201926020929091908290030181600087803b15801561461e57600080fd5b505af1158015614632573d6000803e3d6000fd5b505050506040513d602081101561464857600080fd5b5050604080517f3e3a15600000000000000000000000000000000000000000000000000000000081526004810183905260ff8a1660248201526044810189905260648101889052905173ffffffffffffffffffffffffffffffffffffffff8c1691633e3a15609160848083019260209291908290030181600087803b1580156146d057600080fd5b505af11580156146e4573d6000803e3d6000fd5b505050506040513d60208110156146fa57600080fd5b5050604080517f82b8660000000000000000000000000000000000000000000000000000000000815260ff8a166004820152905160009173ffffffffffffffffffffffffffffffffffffffff8d16916382b8660091602480820192602092909190829003018186803b15801561476f57600080fd5b505afa158015614783573d6000803e3d6000fd5b505050506040513d602081101561479957600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191925060009173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b15801561480d57600080fd5b505afa158015614821573d6000803e3d6000fd5b505050506040513d602081101561483757600080fd5b5051905061485c73ffffffffffffffffffffffffffffffffffffffff8316338361500f565b9c9b505050505050505050505050565b6000808773ffffffffffffffffffffffffffffffffffffffff16638214f5a46040518163ffffffff1660e01b815260040160206040518083038186803b1580156148b557600080fd5b505afa1580156148c9573d6000803e3d6000fd5b505050506040513d60208110156148df57600080fd5b5051604080517f66c0bd2400000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff80841660048301529151929350600092918c16916366c0bd2491602480820192602092909190829003018186803b15801561495757600080fd5b505afa15801561496b573d6000803e3d6000fd5b505050506040513d602081101561498157600080fd5b5051604080517f82b8660000000000000000000000000000000000000000000000000000000000815260ff8b166004820152905191925060009173ffffffffffffffffffffffffffffffffffffffff8d16916382b86600916024808301926020929190829003018186803b1580156149f857600080fd5b505afa158015614a0c573d6000803e3d6000fd5b505050506040513d6020811015614a2257600080fd5b50519050614a4873ffffffffffffffffffffffffffffffffffffffff821633308a6150a1565b8660ff838116908b1614614b2057614a7773ffffffffffffffffffffffffffffffffffffffff83168d8a614ebc565b8b73ffffffffffffffffffffffffffffffffffffffff1663916955868b858b60008b6040518663ffffffff1660e01b8152600401808660ff1681526020018560ff16815260200184815260200183815260200182815260200195505050505050602060405180830381600087803b158015614af157600080fd5b505af1158015614b05573d6000803e3d6000fd5b505050506040513d6020811015614b1b57600080fd5b505190505b614b4173ffffffffffffffffffffffffffffffffffffffff85168c83614ebc565b604080517f3e3a15600000000000000000000000000000000000000000000000000000000081526004810183905260ff8b1660248201526044810189905260648101889052905173ffffffffffffffffffffffffffffffffffffffff8d1691633e3a15609160848083019260209291908290030181600087803b158015614bc757600080fd5b505af1158015614bdb573d6000803e3d6000fd5b505050506040513d6020811015614bf157600080fd5b5050604080517f82b8660000000000000000000000000000000000000000000000000000000000815260ff8b166004820152905160009173ffffffffffffffffffffffffffffffffffffffff8e16916382b8660091602480820192602092909190829003018186803b158015614c6657600080fd5b505afa158015614c7a573d6000803e3d6000fd5b505050506040513d6020811015614c9057600080fd5b5051604080517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152905191925060009173ffffffffffffffffffffffffffffffffffffffff8416916370a08231916024808301926020929190829003018186803b158015614d0457600080fd5b505afa158015614d18573d6000803e3d6000fd5b505050506040513d6020811015614d2e57600080fd5b50519050614d5373ffffffffffffffffffffffffffffffffffffffff8316338361500f565b9d9c50505050505050505050505050565b6000808473ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015614dce57600080fd5b505afa158015614de2573d6000803e3d6000fd5b505050506040513d6020811015614df857600080fd5b50519050614e1e73ffffffffffffffffffffffffffffffffffffffff86168530866150a1565b808573ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b158015614e8657600080fd5b505afa158015614e9a573d6000803e3d6000fd5b505050506040513d6020811015614eb057600080fd5b50510395945050505050565b6000614f79828573ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30876040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015614f4757600080fd5b505afa158015614f5b573d6000803e3d6000fd5b505050506040513d6020811015614f7157600080fd5b505190615136565b6040805173ffffffffffffffffffffffffffffffffffffffff8616602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529091506150099085906151aa565b50505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261509c9084906151aa565b505050565b6040805173ffffffffffffffffffffffffffffffffffffffff80861660248301528416604482015260648082018490528251808303909101815260849091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790526150099085906151aa565b60008282018381101561303757604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b606061520c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166152829092919063ffffffff16565b80519091501561509c5780806020019051602081101561522b57600080fd5b505161509c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061553f602a913960400191505060405180910390fd5b60606152918484600085615299565b949350505050565b6060824710156152f4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806155196026913960400191505060405180910390fd5b6152fd85615454565b61536857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015290519081900360640190fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106153d257805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101615395565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615434576040519150601f19603f3d011682016040523d82523d6000602084013e615439565b606091505b509150915061544982828661545a565b979650505050505050565b3b151590565b60608315615469575081613037565b8251156154795782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156154dd5781810151838201526020016154c5565b50505050905090810190601f16801561550a5780820380516001836020036101000a031916815260200191505b509250505060405180910390fdfe416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c5361666545524332303a204552433230206f7065726174696f6e20646964206e6f742073756363656564a264697066735822122036de88082e3bc240ee338889394e0aebdeb9598eda2986da09b549f0d949c54d64736f6c634300060c0033
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.