Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
ShogunMulticallV1
Compiler Version
v0.8.20+commit.a1b79de6
ZkSolc Version
v1.5.7
Optimization Enabled:
Yes with Mode 3
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// Sources flattened with tronbox v4.0.0 https://tronbox.io // File: @openzeppelin\contracts\token\ERC20\IERC20.sol // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); } // File: @openzeppelin\contracts\token\ERC20\extensions\IERC20Permit.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File: @openzeppelin\contracts\utils\Address.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @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 or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * 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. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @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`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } } // File: @openzeppelin\contracts\token\ERC20\utils\SafeERC20.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; /** * @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; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @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); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @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). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // 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 cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } } // File: @openzeppelin\contracts\utils\Context.sol // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File: @openzeppelin\contracts\access\Ownable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: contracts-tron\utils\TokenRecovery.sol pragma solidity 0.8.20; /// @title Emergency recovery functions abstract contract TokenRecovery is Ownable { using SafeERC20 for IERC20; /** * @param initialOwner Initial smart contract owner */ constructor(address initialOwner) Ownable(initialOwner) {} /** * @notice Emergency recover of stuck ERC20 tokens * @param token ERC20 token address * @param receiver ERC20 tokens receiver address * @dev Can be called only by the owner */ function emergencyERC20Recover( IERC20 token, address receiver ) external onlyOwner { uint256 amount = token.balanceOf(address(this)); token.safeTransfer(receiver, amount); } /** * @notice Emergency recover of stuck native tokens * @param receiver Native tokens receiver address * @dev Can be called only by the owner */ function emergencyEthRecover( address payable receiver ) external onlyOwner { (bool success,) = receiver.call{value: address(this).balance}(""); require(success); } } // File: contracts-tron\libraries\CallParams.sol pragma solidity ^0.8.0; /// @title Library for decoding call params, tightly encoded into bytes32 and updating calldata /// Main purpose - decrease amount of calldata passed to Multicall contract library CallParams { /* Encoded call params (256 bits total) (160 bits) - token address that should be approved/checked `balanceOf(address(this))` (8 bits) - uint8 index of calldata word which should be replaced with `balanceOf(address(this))` (8 bits) - uint8 index of calldata word which should adjusted proportionally to `balanceOf(address(this))` Example usage: adjust `amountOutMin` proportionally to difference between `balanceOf` and `amountIn` (8 bits) - uint8 index of calldata word which should adjusted proportionally to native balance Example usage: adjust `amountOutMin` proportionally to difference between address(this).balance and `amountIn` (8 bits) - uint8 index of calldata word which should be considered as amountIn for approval ... empty bits ... (1 bit) - boolean, true = should approve tokens if required (1 bit) - boolean, true = should update calldata value proportionally to `balanceOf(address(this))` difference (1 bit) - boolean, true = should replace calldata value with `balanceOf(address(this))` (1 bit) - boolean, true = should update calldata value proportionally to native balance difference (1 bit) - boolean, true = should pass full native balance */ type Params is bytes32; // bits shift right values uint256 private constant PASS_FULL_NATIVE_BALANCE_SHR = 0; uint256 private constant REPLACE_NATIVE_BALANCE_SHR = 1; uint256 private constant PROPORTIONALLY_UPDATE_NATIVE_BALANCE_SHR = 2; uint256 private constant REPLACE_BALANCE_OF_SHR = 3; uint256 private constant PROPORTIONALLY_UPDATE_BALANCE_OF_SHR = 4; uint256 private constant APPROVE_SHR = 5; uint256 private constant TOKEN_ADDRESS_SHR = 256 - 160; uint256 private constant BALANCE_OF_REPLACE_INDEX_SHR = 256 - 160 - 8; uint256 private constant NATIVE_BALANCE_REPLACE_INDEX_SHR = 256 - 160 - 8 * 2; uint256 private constant UPDATE_PROPORTIONALLY_TO_BALANCE_OF_INDEX_SHR = 256 - 160 - 8 * 3; uint256 private constant UPDATE_PROPORTIONALLY_TO_NATIVE_BALANCE_INDEX_SHR = 256 - 160 - 8 * 4; uint256 private constant AMOUNT_IN_INDEX_SHR = 256 - 160 - 8 * 5; // Special params bytes32 private constant SLIPPAGE_CHECK = 0xF000000000000000000000000000000000000000000000000000000000000000; error InvalidIndex(uint32 startIndex, uint32 calldataLength); /** * @notice Returns ERC20 token decoded from params that we want to use for * - approval in case of `shouldApproveIfRequired` * - value replacement in case of `shouldReplaceBalanceOf` * - value update in case of `shouldUpdateProportionallyToBalanceOf` * @param params Call params */ function getToken(Params params) internal pure returns (IERC20 token) { assembly { token := and( shr(TOKEN_ADDRESS_SHR, params), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) } } // -------------------------- SPECIAL PARAMS -------------------------- /** * @notice Returns true slippage check is required * @param params Call params * @dev This means no external call will be required. The only thing to do now is check slippage */ function checkSlippage(Params params) internal pure returns (bool) { return Params.unwrap(params) == SLIPPAGE_CHECK; } // -------------------------- CALLDATA FUNCTIONS -------------------------- /** * @notice Updates calldata according to requirements * @param params Call params * @param callData Calldata */ function updateCallData( Params params, bytes memory callData, uint256 initialMsgValue ) internal view { if (shouldReplaceBalanceOf(params)) { // usually for updating `amountIn` uint256 balance = getToken(params).balanceOf(address(this)); uint8 indexToReplace = getIndexToReplaceWithBalanceOf(params); if (shouldUpdateProportionallyToBalanceOf(params)) { // usually for updating `amountOutMin` uint256 currentValue = getCalldataValueAtIndex( callData, indexToReplace ); uint8 indexToUpdate = getIndexToUpdateProportionallyToBalanceOf(params); uint256 currentValueToReplace = getCalldataValueAtIndex( callData, indexToUpdate ); // replacing value proportionally to difference with balanceOf amount replaceCalldataValue( callData, indexToUpdate, currentValueToReplace * balance / currentValue ); } replaceCalldataValue( callData, indexToReplace, balance ); } // if msg. value doesn't change - no need to update calldata if (shouldPassFullNativeBalance(params)) { uint256 nativeBalance = address(this).balance; if (shouldReplaceNativeBalance(params)) { uint8 indexToReplace = getIndexToReplaceWithNativeBalance(params); replaceCalldataValue( callData, indexToReplace, nativeBalance ); } if (shouldUpdateProportionallyToNativeBalance(params)) { uint8 indexToUpdate = getIndexToUpdateProportionallyToNativeBalance(params); // usually for updating `amountOutMin` uint256 currentValueToReplace = getCalldataValueAtIndex( callData, indexToUpdate ); // replacing value proportionally to difference with native balance amount replaceCalldataValue( callData, indexToUpdate, currentValueToReplace * nativeBalance / initialMsgValue ); } } } /** * @notice Replaces calldata value at `index` with `newValue` * @param callData Calldata memory * @param index Index of 32-byte calldata word to replace * @param newValue New value to replace with */ function replaceCalldataValue( bytes memory callData, uint8 index, uint256 newValue ) internal pure { uint256 startIndex = getStartIndex(callData.length, index); assembly { mstore(add(callData, startIndex), newValue) } } /** * @notice Gets uint256 calldata value from specific index * @param callData Calldata memory * @param index Index of 32-byte calldata word to get * @return value uint256 value */ function getCalldataValueAtIndex( bytes memory callData, uint8 index ) internal pure returns(uint256 value) { uint256 startIndex = getStartIndex(callData.length, index); assembly { value := mload(add(callData, startIndex)) } } /** * @notice Gets amountIn value for approval (amountToSpend) * @param params Call params * @param callData Calldata memory * @return amountIn Amount of tokens that expected to be spent */ function getAmountIn( Params params, bytes memory callData ) internal pure returns(uint256 amountIn) { uint256 startIndex = getStartIndex( callData.length, getIndexOfAmountIn(params) ); assembly { amountIn := mload(add(callData, startIndex)) } } /** * @notice Gets start index for specific value in calldata * @param callDataLength Calldata length * @param index Index of 32-byte calldata word * @return startIndex Start index of value in calldata */ function getStartIndex(uint256 callDataLength, uint256 index) private pure returns(uint256 startIndex) { // 32 for prefix + 4 for selector startIndex = 32 + 4 + index * 32; if (startIndex > callDataLength) { revert InvalidIndex(uint32(startIndex), uint32(callDataLength)); } } // -------------------------- BOOLEAN ENCODING -------------------------- /** * @notice Should this call pass all smart contracts native balance as `msg.value`? * @param params Call params */ function shouldPassFullNativeBalance(Params params) internal pure returns (bool value) { assembly {value := and(shr(PASS_FULL_NATIVE_BALANCE_SHR, params), 1)} } /** * @notice Do we want to update calldata value proportionally to difference * between native tokens balance and value at `indexOfAmountIn` in calldata * {newValue} = {oldValue} * {nativeBalance} / {amountIn}? * @param params Call params */ function shouldUpdateProportionallyToNativeBalance(Params params) internal pure returns (bool value) { assembly {value := and(shr(PROPORTIONALLY_UPDATE_NATIVE_BALANCE_SHR, params), 1)} } /** * @notice do we want to replace calldata value with amount * of ERC20 tokens available at the moment before the call? (`balanceOf(address(this))`) * @param params Call params */ function shouldReplaceBalanceOf(Params params) internal pure returns (bool value) { assembly {value := and(shr(REPLACE_BALANCE_OF_SHR, params), 1)} } /** * @notice Do we want to replace calldata value with amount * of native tokens available at the moment before the call? * @param params Call params */ function shouldReplaceNativeBalance(Params params) internal pure returns (bool value) { assembly {value := and(shr(REPLACE_NATIVE_BALANCE_SHR, params), 1)} } /** * @notice Do we want to update calldata value proportionally to difference * between ERC20 tokens balance and value at `indexOfAmountIn` in calldata * {newValue} = {oldValue} * {erc20Balance} / {amountIn}? * @param params Call params */ function shouldUpdateProportionallyToBalanceOf(Params params) internal pure returns (bool value) { assembly {value := and(shr(PROPORTIONALLY_UPDATE_BALANCE_OF_SHR, params), 1)} } /** * @notice Do we want to approve ERC20 token to the target we're about to call? * (usually it's a router contract) * @param params Call params */ function shouldApproveIfRequired(Params params) internal pure returns (bool value) { assembly {value := and(shr(APPROVE_SHR, params), 1)} } // -------------------------- INDEX ENCODING -------------------------- /** * @notice Returns index of calldata value that should be replaced with balanceOf amount * @param params Call params */ function getIndexToReplaceWithBalanceOf(Params params) internal pure returns (uint8 index) { assembly {index := and(shr(BALANCE_OF_REPLACE_INDEX_SHR, params), 0xFF)} } /** * @notice Returns index of calldata value that should be updated proportionally to token balanceOf * @param params Call params */ function getIndexToUpdateProportionallyToBalanceOf(Params params) internal pure returns (uint8 index) { assembly {index := and(shr(UPDATE_PROPORTIONALLY_TO_BALANCE_OF_INDEX_SHR, params), 0xFF)} } /** * @notice Returns index of calldata value that should be replaced with native balance * @param params Call params */ function getIndexToReplaceWithNativeBalance(Params params) internal pure returns (uint8 index) { assembly {index := and(shr(REPLACE_NATIVE_BALANCE_SHR, params), 0xFF)} } /** * @notice Returns index of calldata value that should be updated proportionally to native balance * @param params Call params */ function getIndexToUpdateProportionallyToNativeBalance(Params params) internal pure returns (uint8 index) { assembly {index := and(shr(UPDATE_PROPORTIONALLY_TO_NATIVE_BALANCE_INDEX_SHR, params), 0xFF)} } /** * @notice Returns index of value in calldata that should be considered as * {amountIn} in case of `shouldUpdateProportionallyToNativeBalance` * and `shouldUpdateProportionallyToBalanceOf` calculations * @param params Call params */ function getIndexOfAmountIn(Params params) internal pure returns (uint8 index) { assembly {index := and(shr(AMOUNT_IN_INDEX_SHR, params), 0xFF)} } } // File: contracts-tron\interfaces\IShogunMulticallV1.sol pragma solidity 0.8.20; interface IShogunMulticallV1 { struct Call { CallParams.Params params; // encoded params address target; // `call.to` - address of smart contract that should be called uint256 msgValue; // `msg.value` that should be attached to the call bytes data; // `call.data` that should be passed to the call } /** * @notice Executes multiple calls * @param calls Encoded array of calls that must be executed * @param swapTokenOut Token OUT address (address(0) if native token) for swap calls * @param swapDestination Receiver of Tokens OUT after swap * @param swapAmountOutMin Minimum amount to receive after swap */ function multicall( Call[] memory calls, address swapTokenOut, address swapDestination, uint256 swapAmountOutMin ) external payable; } // File: contracts-tron\ShogunMulticallV1.sol pragma solidity 0.8.20; /// @title Multicall contract designed to interact with DEXes for efficient swaps /// Supports multiple routes, split routes /// Allows adjusting `amountIn`, `amountOutMin` and other values depending on token balance and native balance. contract ShogunMulticallV1 is TokenRecovery, IShogunMulticallV1 { using SafeERC20 for IERC20; using CallParams for CallParams.Params; error BelowAmountOutMin(uint256 received); error CallFailed(uint256 index, bytes errorData); /** * @param initialOwner Initial smart contract owner */ constructor(address initialOwner) TokenRecovery(initialOwner) {} receive() external payable {} /** * @notice Executes multiple calls * @param calls Encoded array of calls that must be executed * @param swapTokenOut Token OUT address (address(0) if native token) for swap calls * @param swapDestination Receiver of Tokens OUT after swap * @param swapAmountOutMin Minimum amount to receive after swap */ function multicall( Call[] memory calls, address swapTokenOut, address swapDestination, uint256 swapAmountOutMin ) external payable { uint256 initialAmount = _getBalance(swapTokenOut, swapDestination); for(uint256 i = 0; i < calls.length; i++) { Call memory call = calls[i]; // special params case - no call is required if (call.params.checkSlippage()) { uint256 received = _getBalance(swapTokenOut, swapDestination) - initialAmount; if (received < swapAmountOutMin) revert BelowAmountOutMin(received); continue; } call.params.updateCallData(call.data, call.msgValue); if (call.params.shouldApproveIfRequired()) { _safeApproveIfRequired( call.params.getToken(), call.target, call.params.getAmountIn(call.data) ); } if (call.params.shouldPassFullNativeBalance()) { call.msgValue = address(this).balance; } (bool success, bytes memory data) = call.target.call{value: call.msgValue}(call.data); if (!success) revert CallFailed(i, data); } } /** * @notice Approves ERC20 token to `spender` in case of insufficient allowance * @param token ERC20 token that needs to be approved * @param spender Spender address * @param amountToSpend Amount of tokens to spend */ function _safeApproveIfRequired( IERC20 token, address spender, uint256 amountToSpend ) internal { uint256 allowance = token.allowance(address(this), spender); if (allowance < amountToSpend) { // Approves to 0 in case token processes `approve` like `increaseAllowance` if (allowance != 0) { token.forceApprove(spender, 0); } token.forceApprove(spender, type(uint256).max); } } /** * @notice Returns balance of token OUT * @param token ERC20 token address (address(0) if native token) * @param account Account, which balance should be checked */ function _getBalance( address token, address account ) internal view returns(uint256) { if (token == address(0)) { return account.balance; } else { return IERC20(token).balanceOf(account); } } }
{ "optimizer": { "enabled": true, "mode": "3" }, "evmVersion": "paris", "outputSelection": { "*": { "*": [ "abi", "metadata" ], "": [ "ast" ] } }, "detectMissingLibraries": false, "forceEVMLA": false, "enableEraVMExtensions": false, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"initialOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"received","type":"uint256"}],"name":"BelowAmountOutMin","type":"error"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bytes","name":"errorData","type":"bytes"}],"name":"CallFailed","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"uint32","name":"startIndex","type":"uint32"},{"internalType":"uint32","name":"calldataLength","type":"uint32"}],"name":"InvalidIndex","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"receiver","type":"address"}],"name":"emergencyERC20Recover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"receiver","type":"address"}],"name":"emergencyEthRecover","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"CallParams.Params","name":"params","type":"bytes32"},{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"msgValue","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IShogunMulticallV1.Call[]","name":"calls","type":"tuple[]"},{"internalType":"address","name":"swapTokenOut","type":"address"},{"internalType":"address","name":"swapDestination","type":"address"},{"internalType":"uint256","name":"swapAmountOutMin","type":"uint256"}],"name":"multicall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
9c4d535b00000000000000000000000000000000000000000000000000000000000000000100021f5c782e4d3aa628bbc412b1325d31b579c9cf46a56cb71ad0ca142c3500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000020000000000000000000000000d022311dacaa30f8396ca9d2c4662a2ef083a1dd
Deployed Bytecode
0x000200000000000200140000000000020000006003100270000001ee03300197000100000031035500000001002001900000002a0000c13d0000008002000039000000400020043f000000040030008c000000590000413d000000000201043b000000e002200270000001f80020009c0000005d0000213d000001fc0020009c000000780000613d000001fd0020009c000000960000613d000001fe0020009c000002150000c13d0000000001000416000000000001004b000002150000c13d000000000100041a000001f1051001970000000002000411000000000025004b000000f30000c13d000001f201100197000000000010041b0000000001000414000001ee0010009c000001ee01008041000000c001100210000001f3011001c70000800d020000390000000303000039000001f404000041000000000600001907b207a80000040f000002130000013d0000000002000416000000000002004b000002150000c13d0000001f02300039000001ef022001970000008002200039000000400020043f0000001f0430018f000001f00530019800000080025000390000003b0000613d0000008006000039000000000701034f000000007807043c0000000006860436000000000026004b000000370000c13d000000000004004b000000480000613d000000000151034f0000000304400210000000000502043300000000054501cf000000000545022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f0000000000120435000000200030008c000002150000413d000000800100043d000001f10010009c000002150000213d000001f106100198000000de0000c13d000000400100043d000001f602000041000000000021043500000004021000390000000000020435000001ee0010009c000001ee010080410000004001100210000001f7011001c7000007b400010430000000000003004b000002150000c13d0000000001000019000007b30001042e000001f90020009c000000b20000613d000001fa0020009c000000d60000613d000001fb0020009c000002150000c13d000000240030008c000002150000413d0000000002000416000000000002004b000002150000c13d0000000401100370000000000601043b000001f10060009c000002150000213d000000000100041a000001f1051001970000000002000411000000000025004b000000f30000c13d000000000006004b000000fd0000c13d000001f601000041000000800010043f000000840000043f0000020001000041000007b400010430000000440030008c000002150000413d0000000002000416000000000002004b000002150000c13d0000000402100370000000000502043b000001f10050009c000002150000213d0000002401100370000000000601043b000001f10060009c000002150000213d000000000100041a000001f1021001970000000001000411000000000012004b000000f80000c13d0000020a01000041000000800010043f0000000001000410000000840010043f0000000001000414000000040050008c000001350000c13d0000000003000031000000200030008c000000200400003900000000040340190000015f0000013d000000840030008c000002150000413d0000000402100370000000000202043b001000000002001d000002040020009c000002150000213d00000010020000290000002302200039000000000032004b000002150000813d00000010020000290000000402200039000000000221034f000000000602043b000002050060009c000000ac0000813d00000005026002100000003f042000390000020604400197000002070040009c0000010a0000a13d0000020e01000041000000000010043f0000004101000039000000040010043f000001f701000041000007b400010430000000240030008c000002150000413d0000000002000416000000000002004b000002150000c13d0000000401100370000000000301043b000001f10030009c000002150000213d000000000100041a000001f1021001970000000001000411000000000012004b000000f80000c13d001000000003001d00000202010000410000000000100443000000000100041000000004001004430000000001000414000001ee0010009c000001ee01008041000000c00110021000000203011001c70000800a0200003907b207ad0000040f0000000100200190000005ee0000613d000000000301043b00000000010004140000001004000029000000040040008c000001780000c13d00000001020000390000000001000031000002110000013d0000000001000416000000000001004b000002150000c13d000000000100041a000001f101100197000000800010043f0000020101000041000007b30001042e000000000100041a000001f202100197000000000262019f000000000020041b0000000002000414000001f105100197000001ee0020009c000001ee02008041000000c001200210000001f3011001c70000800d020000390000000303000039000001f40400004107b207a80000040f0000000100200190000002150000613d000000200100003900000100001004430000012000000443000001f501000041000007b30001042e000001ff01000041000000800010043f000000840020043f0000020001000041000007b400010430000001ff02000041000000800020043f000000840010043f0000020001000041000007b400010430000001f201100197000000000161019f000000000010041b0000000001000414000001ee0010009c000001ee01008041000000c001100210000001f3011001c70000800d020000390000000303000039000001f40400004107b207a80000040f000002130000013d0000008004400039000000400040043f000000800060043f00000010040000290000002404400039000f00000042001d0000000f0030006b000002150000213d000000000006004b0000017f0000c13d0000002402100370000000000202043b000c00000002001d000001f10020009c000002150000213d0000004402100370000000000202043b000700000002001d000001f10020009c000002150000213d0000006401100370000000000101043b000600000001001d0000000001000415000100000001001d0000000c02000029000000000002004b000002400000c13d00000202010000410000000000100443000000070100002900000004001004430000000001000414000001ee0010009c000001ee01008041000000c00110021000000203011001c70000800a0200003907b207ad0000040f0000000100200190000005ee0000613d000000000101043b000002890000013d000f00000006001d000001ee0010009c000001ee01008041000000c00110021000000200011001c7001000000005001d000000000205001907b207ad0000040f0000006003100270000001ee03300197000000200030008c000000200400003900000000040340190000001f0640018f000000200740019000000080057001bf0000014c0000613d0000008008000039000000000901034f000000009a09043c0000000008a80436000000000058004b000001480000c13d000000000006004b000001590000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000000003001f00010000000103550000000100200190000001eb0000613d00000010050000290000000f060000290000001f01400039000000600710018f00000080017001bf000000400010043f000000200030008c000002150000413d000000a002700039000000800300043d00000216040000410000000000420435000000c4027000390000000000320435000000a4027000390000000000620435000000440200003900000000002104350000006402000039001000000005001d000f00000001001d07b206a40000040f00000010010000290000000f0200002907b206b60000040f0000000001000019000007b30001042e000001ee0010009c000001ee01008041000000c001100210000000000003004b000002090000c13d00000000020400190000020c0000013d000000a006000039000e0024003000920000018a0000013d0000000002a50019000000000002043500000060029000390000000000b20435000000000696043600000020044000390000000f0040006c000001140000813d000000000241034f000000000202043b000002040020009c000002150000213d000000100a2000290000000e02a00069000002080020009c000002150000213d000000800020008c000002150000413d000000400900043d000002070090009c000000ac0000213d0000008002900039000000400020043f0000002402a00039000000000221034f000000000202043b0000000002290436000000440ba000390000000005b1034f000000000505043b000001f10050009c000002150000213d00000000005204350000002002b00039000000000221034f000000000202043b000000400590003900000000002504350000004002b00039000000000221034f000000000202043b000002040020009c000002150000213d000000000da200190000004302d00039000000000032004b000000000500001900000209050080410000020902200197000000000002004b000000000a000019000002090a004041000002090020009c000000000a05c01900000000000a004b000002150000c13d000000240ed000390000000002e1034f000000000a02043b0000020400a0009c000000ac0000213d0000001f02a0003900000217022001970000003f022000390000021702200197000000400b00043d00000000022b00190000000000b2004b00000000050000390000000105004039000002040020009c000000ac0000213d0000000100500190000000ac0000c13d000000400020043f0000000005ab04360000000002ad00190000004402200039000000000032004b000002150000213d0000002002e00039000000000221034f000002170fa00198000000000df50019000001dd0000613d000000000e02034f000000000c05001900000000e70e043c000000000c7c04360000000000dc004b000001d90000c13d0000001f0ca00190000001820000613d0000000002f2034f0000000307c00210000000000c0d0433000000000c7c01cf000000000c7c022f000000000202043b0000010007700089000000000272022f00000000027201cf0000000002c2019f00000000002d0435000001820000013d0000001f0530018f000001f006300198000000400200043d0000000004620019000001f60000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000001f20000c13d000000000005004b000002030000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f00000000001404350000006001300210000001ee0020009c000001ee020080410000004002200210000000000112019f000007b400010430000001f3011001c70000800902000039000000000500001907b207a80000040f00010000000103550000006001100270000001ee0010019d000001ee01100197000000000001004b000002170000c13d00000001002001900000005b0000c13d0000000001000019000007b400010430000002040010009c000000ac0000213d0000001f0410003900000217044001970000003f044000390000021705400197000000400400043d0000000005540019000000000045004b00000000060000390000000106004039000002040050009c000000ac0000213d0000000100600190000000ac0000c13d000000400050043f000000000614043600000217031001980000001f0410018f00000000013600190000000105000367000002320000613d000000000705034f000000007807043c0000000006860436000000000016004b0000022e0000c13d000000000004004b000002130000613d000000000335034f0000000304400210000000000501043300000000054501cf000000000545022f000000000303043b0000010004400089000000000343022f00000000034301cf000000000353019f0000000000310435000002130000013d000000400300043d0000020a010000410000000000130435001000000003001d0000000401300039000000070300002900000000003104350000000001000414000000040020008c0000024f0000c13d0000000003000031000000200030008c000000200400003900000000040340190000027a0000013d0000001002000029000001ee0020009c000001ee020080410000004002200210000001ee0010009c000001ee01008041000000c001100210000000000121019f000001f7011001c70000000c0200002907b207ad0000040f0000006003100270000001ee03300197000000200030008c000000200400003900000000040340190000001f0640018f00000020074001900000001005700029000002690000613d000000000801034f0000001009000029000000008a08043c0000000009a90436000000000059004b000002650000c13d000000000006004b000002760000613d000000000771034f0000000306600210000000000805043300000000086801cf000000000868022f000000000707043b0000010006600089000000000767022f00000000066701cf000000000686019f0000000000650435000000000003001f00010000000103550000000100200190000005ef0000613d0000001f01400039000000600210018f0000001001200029000000000021004b00000000020000390000000102004039000002040010009c000000ac0000213d0000000100200190000000ac0000c13d000000400010043f000000200030008c000002150000413d00000010010000290000000001010433000500000001001d000000800100043d000000000001004b000002920000c13d0000000001000415000000010110006900000000010000020000000001000019000007b30001042e00000000020000190000029b0000013d00000001002001900000060b0000613d00000010020000290000000102200039000000800100043d000000000012004b0000028d0000813d001000000002001d0000000501200210000000a001100039000000000a010433000000001c0a04340000020b00c0009c0000000c02000029000002b30000c13d000000000002004b000002ce0000613d000000400a00043d0000020a0100004100000000001a04350000000401a00039000000070300002900000000003104350000000001000414000000040020008c000002dd0000c13d0000000003000031000000200030008c00000020040000390000000004034019000003080000013d000f00000001001d0000004001a00039000b00000001001d0000000001010433000800000001001d0000006001a00039000e00000001001d000000000b0104330000000800c00190000d0000000a001d000003980000613d000000400d00043d0000020a0100004100000000001d04350000000001000410000001f1011001970000000402d00039000000000012043500000000010004140000006002c00270000000040020008c0000031b0000c13d0000000003000031000000200030008c000000200400003900000000040340190000034b0000013d00000202010000410000000000100443000000070100002900000004001004430000000001000414000001ee0010009c000001ee01008041000000c00110021000000203011001c70000800a0200003907b207ad0000040f0000000100200190000005ee0000613d000000000101043b000003160000013d000001ee00a0009c000001ee0300004100000000030a40190000004003300210000001ee0010009c000001ee01008041000000c001100210000000000131019f000001f7011001c7000f0000000a001d07b207ad0000040f0000000f0a0000290000006003100270000001ee03300197000000200030008c00000020040000390000000004034019000000200640019000000000056a0019000002f70000613d000000000701034f00000000080a0019000000007907043c0000000008980436000000000058004b000002f30000c13d0000001f07400190000003040000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000000000003001f00010000000103550000000100200190000006410000613d0000001f01400039000000600210018f0000000001a20019000000000021004b00000000020000390000000102004039000002040010009c000000ac0000213d0000000100200190000000ac0000c13d000000400010043f000000200030008c000002150000413d00000000010a0433000000050110006c000005fb0000413d000000060010006c000002960000813d000006010000013d00090000000c001d000a0000000b001d000001ee00d0009c000001ee0300004100000000030d40190000004003300210000001ee0010009c000001ee01008041000000c001100210000000000131019f000001f7011001c700040000000d001d07b207ad0000040f000000040d0000290000006003100270000001ee03300197000000200030008c00000020040000390000000004034019000000200640019000000000056d0019000003370000613d000000000701034f00000000080d0019000000007907043c0000000008980436000000000058004b000003330000c13d0000001f07400190000003440000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000000000003001f000100000001035500000001002001900000000d0a0000290000000a0b000029000000090c0000290000064d0000613d0000001f01400039000000600210018f0000000001d20019000000000021004b00000000020000390000000102004039000002040010009c000000ac0000213d0000000100200190000000ac0000c13d000000400010043f000000200030008c000002150000413d00000000020d04330000005803c00270000000ff0330018f0000001000c001900000038b0000613d00000000040b0433000000000003004b0000002405000039000003660000613d000000050530021000000000063500d9000000200060008c000005fb0000c13d0000002405500039000000000045004b000006590000213d0000000005b5001900000000050504330000004806c00270000000ff0760019000000005067002100000002408000039000003730000613d00000000087600d9000000200080008c000005fb0000c13d0000002408600039000000000048004b000006610000213d0000000008b80019000000000908043300000000082900a9000000000009004b0000037d0000613d00000000099800d9000000000029004b000005fb0000c13d000000000005004b000006390000613d000000000007004b0000002409000039000003860000613d00000000077600d9000000200070008c000005fb0000c13d0000002409600039000000000049004b0000068b0000213d00000000015800d90000000004b90019000000000014043500000000010b0433000000000003004b0000002404000039000003940000613d000000050430021000000000033400d9000000200030008c000005fb0000c13d0000002404400039000000000014004b000006300000213d0000000001b4001900000000002104350000000100c00190000003e10000613d00090000000c001d000a0000000b001d00000202010000410000000000100443000000000100041000000004001004430000000001000414000001ee0010009c000001ee01008041000000c00110021000000203011001c70000800a0200003907b207ad0000040f0000000100200190000005ee0000613d000000000101043b000000090500002900000002005001900000000d0a0000290000000a07000029000003bd0000613d00000000020704330000000103500270000000ff043001900000002403000039000003b90000613d000000050340021000000000044300d9000000200040008c000005fb0000c13d0000002403300039000000000023004b000006690000213d000000000273001900000000001204350000000400500190000003e10000613d00000000020704330000004003500270000000ff0430019000000005034002100000002405000039000003c90000613d00000000054300d9000000200050008c000005fb0000c13d0000002405300039000000000025004b000006720000213d0000000005750019000000000605043300000000051600a9000000000006004b000003d30000613d00000000066500d9000000000016004b000005fb0000c13d000000080000006b000006390000613d000000000004004b0000002401000039000003dc0000613d00000000014300d9000000200010008c000005fb0000c13d0000002401300039000000000021004b000006970000213d00000008025000fa0000000001710019000000000021043500000000010a04330000002000100190000005890000613d0000000e02000029000000000202043300000000030204330000000f0400002900000000040404330000003805100270000000ff065001900000002405000039000003f20000613d000000050560021000000000066500d9000000200060008c000005fb0000c13d0000002405500039000000000035004b0000063f0000213d000001f103400197000000000225001900000000050204330000000002000415000800000002001d000000400d00043d0000002402d00039000900000003001d00000000003204350000020f0200004100000000002d04350000000402d00039000000000300041000000000003204350000000002000414000000600b1002700000000400b0008c000a0000000b001d0000040c0000c13d0000000003000031000000200030008c000000200400003900000000040340190000043c0000013d000300000005001d000001ee00d0009c000001ee0100004100000000010d40190000004001100210000001ee0020009c000001ee02008041000000c002200210000000000112019f0000020d011001c700000000020b001900040000000d001d07b207ad0000040f000000040d0000290000006003100270000001ee03300197000000200030008c00000020040000390000000004034019000000200640019000000000056d0019000004280000613d000000000701034f00000000080d0019000000007907043c0000000008980436000000000058004b000004240000c13d0000001f07400190000004350000613d000000000661034f0000000307700210000000000805043300000000087801cf000000000878022f000000000606043b0000010007700089000000000676022f00000000067601cf000000000686019f0000000000650435000000000003001f000100000001035500000001002001900000000d0a0000290000000a0b0000290000067f0000613d00000003050000290000001f01400039000000600110018f000000000cd1001900000000001c004b000000000100003900000001010040390000020400c0009c000000ac0000213d0000000100100190000000ac0000c13d0000004000c0043f000000200030008c000002150000413d00000000010d0433000000000051004b000005850000813d000000000001004b000004e60000613d0000002002c00039000002100100004100000000001204350000002401c0003900000009040000290000000000410435000000440100003900000000001c04350000004401c0003900000000000104350000020700c0009c000000ac0000213d0000008001c00039000000400010043f00000000050c043300000000040004140000000400b0008c00040000000c001d000004650000c13d000002040030009c00000001020000390000047a0000a13d000000ac0000013d000001ee0020009c000001ee020080410000004001200210000001ee0050009c000001ee050080410000006002500210000000000112019f000001ee0040009c000001ee04008041000000c002400210000000000121019f00000000020b001907b207a80000040f000000010220018f00010000000103550000006001100270000001ee0010019d000001ee03100198000004cc0000613d000000400100043d0000000a0b0000290000001f0430003900000211044001970000003f0440003900000212054001970000000004150019000000000054004b00000000050000390000000105004039000002040040009c000000ac0000213d0000000100500190000000ac0000c13d000000400040043f0000000004310436000002170630019800000000056400190000000107000367000004920000613d000000000807034f0000000009040019000000008a08043c0000000009a90436000000000059004b0000048e0000c13d0000001f033001900000049f0000613d000000000667034f0000000303300210000000000705043300000000073701cf000000000737022f000000000606043b0000010003300089000000000636022f00000000033601cf000000000373019f0000000000350435000000000002004b000004d10000613d0000000002000415000000120220008a00000005022002100000000001010433000000000001004b000004b60000613d000002080010009c000002150000213d000000200010008c000002150000413d0000000001040433000000000001004b0000000002000039000000010200c039000000000021004b000002150000c13d0000000002000415000000110220008a0000000502200210000000000001004b000004d10000613d000300000002001d000002130100004100000000001004430000000400b004430000000001000414000001ee0010009c000001ee01008041000000c00110021000000203011001c7000080020200003907b207ad0000040f0000000100200190000005ee0000613d000000000101043b000000000001004b00000003010000290000000501100270000000000100003f000000010100c03f0000000a0b000029000004e60000c13d000004d10000013d000000800400003900000060010000390000000a0b000029000000000002004b000004a10000c13d000000400200043d0000002001200039000002100300004100000000003104350000002401200039000000090300002900000000003104350000004401000039000000000012043500000044012000390000000000010435000002070020009c000000ac0000213d0000008001200039000000400010043f00000000010b001907b206b60000040f0000000a01000029000000040200002907b206b60000040f0000000a0b0000290000000001000415000300000001001d000000400400043d0000004401400039000000010200008a000000000021043500000020014000390000021002000041000000000021043500000024024000390000000903000029000000000032043500000044020000390000000000240435000400000004001d000002070040009c000000ac0000213d00000004030000290000008002300039000000400020043f000000000303043300000000020004140000000400b0008c000005010000c13d00000000040000310000000102000039000005140000013d000001ee0010009c000001ee010080410000004001100210000001ee0030009c000001ee030080410000006003300210000000000113019f000001ee0020009c000001ee02008041000000c002200210000000000121019f00000000020b001907b207a80000040f0000000a0b000029000000010220018f00010000000103550000006001100270000001ee0010019d000001ee04100197000000000004004b00000080010000390000006003000039000005400000613d000002040040009c000000ac0000213d0000001f0140003900000217011001970000003f011000390000021701100197000000400300043d0000000001130019000000000031004b00000000050000390000000105004039000002040010009c000000ac0000213d0000000100500190000000ac0000c13d000000400010043f0000000001430436000002170640019800000000056100190000000107000367000005330000613d000000000807034f0000000009010019000000008a08043c0000000009a90436000000000059004b0000052f0000c13d0000001f04400190000005400000613d000000000667034f0000000304400210000000000705043300000000074701cf000000000747022f000000000606043b0000010004400089000000000646022f00000000044601cf000000000474019f0000000000450435000000000002004b0000056d0000613d0000000004000415000000140440008a00000005044002100000000002030433000000000002004b000005570000613d000002080020009c000002150000213d000000200020008c000002150000413d0000000001010433000000000001004b0000000002000039000000010200c039000000000021004b000002150000c13d0000000004000415000000130440008a0000000504400210000000000001004b0000056d0000613d000200000004001d000002130100004100000000001004430000000400b004430000000001000414000001ee0010009c000001ee01008041000000c00110021000000203011001c7000080020200003907b207ad0000040f0000000100200190000005ee0000613d000000000101043b000000000001004b00000002010000290000000501100270000000000100003f000000010100c03f0000000d0a0000290000000a0b000029000005820000c13d000000400200043d0000002001200039000002100300004100000000003104350000002401200039000000090300002900000000003104350000004401000039000000000012043500000044012000390000000000010435000002070020009c000000ac0000213d0000008001200039000000400010043f00000000010b001907b206b60000040f0000000a01000029000000040200002907b206b60000040f0000000d0a00002900000000010004150000000301100069000000000100000200000000010004150000000801100069000000000100000200000000010a043300000001001001900000058e0000c13d0000000b0100002900000000030104330000059e0000013d00000202010000410000000000100443000000000100041000000004001004430000000001000414000001ee0010009c000001ee01008041000000c00110021000000203011001c70000800a0200003907b207ad0000040f0000000100200190000005ee0000613d000000000301043b0000000b0100002900000000003104350000000e01000029000000000101043300000000250104340000000f0100002900000000040104330000000001000414000001f104400197000000040040008c000005aa0000c13d00000000040000310000000102000039000005c10000013d000001ee0050009c000001ee050080410000006005500210000001ee0020009c000001ee020080410000004002200210000000000225019f000001ee0010009c000001ee01008041000000c001100210000000000112019f000000000003004b000005bb0000613d000001f3011001c700008009020000390000000005000019000005bc0000013d000000000204001907b207a80000040f00010000000103550000006001100270000001ee0010019d000001ee04100197000000000004004b00000080010000390000006003000039000002940000613d000002040040009c000000ac0000213d0000001f0140003900000217011001970000003f011000390000021701100197000000400300043d0000000001130019000000000031004b00000000050000390000000105004039000002040010009c000000ac0000213d0000000100500190000000ac0000c13d000000400010043f0000000001430436000002170640019800000000056100190000000107000367000005e00000613d000000000807034f0000000009010019000000008a08043c0000000009a90436000000000059004b000005dc0000c13d0000001f04400190000002940000613d000000000667034f0000000304400210000000000705043300000000074701cf000000000747022f000000000606043b0000010004400089000000000646022f00000000044601cf000000000474019f0000000000450435000002940000013d000000000001042f0000001f0530018f000001f006300198000000400200043d0000000004620019000001f60000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000005f60000c13d000001f60000013d0000020e01000041000000000010043f0000001101000039000000040010043f000001f701000041000007b400010430000000400200043d0000021503000041000000000032043500000004032000390000000000130435000001ee0020009c000001ee020080410000004001200210000001f7011001c7000007b400010430000000400200043d000000240420003900000040050000390000000000540435000002140400004100000000004204350000000404200039000000100500002900000000005404350000000003030433000000440420003900000000003404350000006404200039000000000003004b000006220000613d000000000500001900000000064500190000000007510019000000000707043300000000007604350000002005500039000000000035004b0000061b0000413d0000001f0130003900000217011001970000000003340019000000000003043500000000012100490000000001410019000001ee0010009c000001ee010080410000006001100210000001ee0020009c000001ee020080410000004002200210000000000121019f000007b400010430000001ee01100197000000400200043d000000240320003900000000001304350000020c010000410000000000120435000000040120003900000000004104350000067a0000013d0000020e01000041000000000010043f0000001201000039000000040010043f000001f701000041000007b400010430000001ee01300197000006730000013d0000001f0530018f000001f006300198000000400200043d0000000004620019000001f60000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000006480000c13d000001f60000013d0000001f0530018f000001f006300198000000400200043d0000000004620019000001f60000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000006540000c13d000001f60000013d000001ee02400197000000240310003900000000002304350000020c02000041000000000021043500000004021000390000000000520435000006920000013d000001ee02400197000000240310003900000000002304350000020c02000041000000000021043500000004021000390000000000820435000006920000013d000001ee01200197000000400200043d000000240420003900000000001404350000020c010000410000000000120435000000040120003900000000003104350000067a0000013d000001ee01200197000000400200043d000000240320003900000000001304350000020c01000041000000000012043500000004012000390000000000510435000001ee0020009c000001ee0200804100000040012002100000020d011001c7000007b4000104300000001f0530018f000001f006300198000000400200043d0000000004620019000001f60000613d000000000701034f0000000008020019000000007907043c0000000008980436000000000048004b000006860000c13d000001f60000013d000001ee02400197000000240310003900000000002304350000020c02000041000000000021043500000004021000390000000000920435000001ee0010009c000001ee0100804100000040011002100000020d011001c7000007b400010430000001ee02200197000000400300043d000000240430003900000000002404350000020c02000041000000000023043500000004023000390000000000120435000001ee0030009c000001ee0300804100000040013002100000020d011001c7000007b4000104300000001f0220003900000217022001970000000001120019000000000021004b00000000020000390000000102004039000002040010009c000006b00000213d0000000100200190000006b00000c13d000000400010043f000000000001042d0000020e01000041000000000010043f0000004101000039000000040010043f000001f701000041000007b400010430000400000000000200000000340204340000000002000414000001f10a1001970000000400a0008c000006e70000c13d0000000001000032000007220000613d000002050010009c0000077d0000813d0000001f0310003900000217033001970000003f033000390000021703300197000000400b00043d00000000033b00190000000000b3004b00000000040000390000000104004039000002040030009c0000077d0000213d00000001004001900000077d0000c13d000000400030043f00000000051b043600000217021001980000001f0310018f00000000012500190000000104000367000006d90000613d000000000604034f000000006706043c0000000005750436000000000015004b000006d50000c13d000000000003004b000007230000613d000000000224034f0000000303300210000000000401043300000000043401cf000000000434022f000000000202043b0000010003300089000000000232022f00000000023201cf000000000242019f0000000000210435000007230000013d000001ee0040009c000001ee040080410000006001400210000001ee0030009c000001ee030080410000004003300210000000000131019f000001ee0020009c000001ee02008041000000c002200210000000000121019f00020000000a001d00000000020a001907b207a80000040f00010000000103550000006003100270000001ee0030019d000001ee04300198000007450000613d0000001f03400039000001ef033001970000003f033000390000021803300197000000400b00043d00000000033b00190000000000b3004b00000000050000390000000105004039000002040030009c000000020a0000290000077d0000213d00000001005001900000077d0000c13d000000400030043f0000001f0540018f00000000034b0436000001f0064001980000000004630019000007140000613d000000000701034f0000000008030019000000007907043c0000000008980436000000000048004b000007100000c13d000000000005004b000007480000613d000000000161034f0000000305500210000000000604043300000000065601cf000000000656022f000000000101043b0000010005500089000000000151022f00000000015101cf000000000161019f0000000000140435000007480000013d000000600b0000390000000002000415000000040220008a000000050220021000000000010b0433000000000001004b000007500000c13d00010000000b001d00020000000a001d00000213010000410000000000100443000000040100003900000004001004430000000001000414000001ee0010009c000001ee01008041000000c00110021000000203011001c7000080020200003907b207ad0000040f0000000100200190000007930000613d0000000002000415000000040220008a0000000502200210000000000101043b000000000001004b000000010b000029000007670000c13d000000400100043d0000021b02000041000000000021043500000004021000390000000403000039000007a10000013d000000600b0000390000008003000039000000020a00002900000000010b04330000000100200190000007890000613d0000000002000415000000030220008a0000000502200210000000000001004b000007530000613d000000050220027000000000020b001f0000076d0000013d00010000000b001d000002130100004100000000001004430000000400a004430000000001000414000001ee0010009c000001ee01008041000000c00110021000000203011001c7000080020200003907b207ad0000040f0000000100200190000007930000613d0000000002000415000000030220008a0000000502200210000000000101043b000000000001004b000000010b0000290000079c0000613d00000000010b0433000000050220027000000000020b001f000000000001004b000000020a0000290000077a0000613d000002080010009c0000077b0000213d0000001f0010008c0000077b0000a13d0000002001b000390000000001010433000000000001004b0000000002000039000000010200c039000000000021004b0000077b0000c13d000000000001004b000007830000613d000000000001042d0000000001000019000007b4000104300000020e01000041000000000010043f0000004101000039000000040010043f000001f701000041000007b400010430000000400100043d0000021c02000041000000000021043500000004021000390000000000a20435000007a20000013d000000000001004b000007940000c13d000000400100043d00000219020000410000000000210435000001ee0010009c000001ee0100804100000040011002100000021a011001c7000007b400010430000000000001042f000001ee0030009c000001ee030080410000004002300210000001ee0010009c000001ee010080410000006001100210000000000121019f000007b400010430000000400100043d0000021b020000410000000000210435000000040210003900000002030000290000000000320435000001ee0010009c000001ee010080410000004001100210000001f7011001c7000007b400010430000000000001042f000007ab002104210000000102000039000000000001042d0000000002000019000000000001042d000007b0002104230000000102000039000000000001042d0000000002000019000000000001042d000007b200000432000007b30001042e000007b40001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000000000000000000000ffffffe0000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e000000002000000000000000000000000000000400000010000000000000000001e4fbdf700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000000000000000000000831bad0200000000000000000000000000000000000000000000000000000000831bad03000000000000000000000000000000000000000000000000000000008da5cb5b00000000000000000000000000000000000000000000000000000000f2fde38b000000000000000000000000000000000000000000000000000000006660473c000000000000000000000000000000000000000000000000000000006a1bac4300000000000000000000000000000000000000000000000000000000715018a6118cdaa700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000080000000000000000000000000000000000000000000000000000000200000008000000000000000009cc7f708afc65944829bd487b90b72536b1951864fbfc14e125fc972a6507f390200000200000000000000000000000000000024000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffff00000000000000000000000000000000000000000000000100000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0000000000000000000000000000000000000000000000000ffffffffffffff7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000000000000000000000000000000000000000000000000000000000000070a0823100000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000000000000ec08253d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000004e487b7100000000000000000000000000000000000000000000000000000000dd62ed3e00000000000000000000000000000000000000000000000000000000095ea7b300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffffffffffe0000000000000000000000000000000000000000000000003ffffffffffffffe01806aa1896bbf26568e884a7374b41e002500962caba6a15023a8d90e8508b835c0dee5d00000000000000000000000000000000000000000000000000000000ff5f293c00000000000000000000000000000000000000000000000000000000a9059cbb00000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000000000003ffffffe01425ea420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000009996b315000000000000000000000000000000000000000000000000000000005274afe70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006a7116ee42d8d6c276218e80640bbd80110410837c8fc01918bf081b78fc6ca6
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000d022311dacaa30f8396ca9d2c4662a2ef083a1dd
-----Decoded View---------------
Arg [0] : initialOwner (address): 0xD022311DAcaa30f8396cA9d2C4662a2eF083A1Dd
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d022311dacaa30f8396ca9d2c4662a2ef083a1dd
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.