More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 291 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Aggregate | 5286241 | 166 days ago | IN | 0 ETH | 0.00000203 | ||||
Aggregate | 5275009 | 166 days ago | IN | 0 ETH | 0.00000319 | ||||
Aggregate | 5266445 | 166 days ago | IN | 0 ETH | 0.00000426 | ||||
Aggregate | 5251507 | 167 days ago | IN | 0 ETH | 0.00000428 | ||||
Aggregate | 5251438 | 167 days ago | IN | 0 ETH | 0.00000431 | ||||
Aggregate | 5245947 | 167 days ago | IN | 0 ETH | 0.00000114 | ||||
Aggregate | 5245871 | 167 days ago | IN | 0 ETH | 0.00000116 | ||||
Aggregate | 5245800 | 167 days ago | IN | 0 ETH | 0.00000234 | ||||
Aggregate | 5245762 | 167 days ago | IN | 0 ETH | 0.00000122 | ||||
Aggregate | 5245647 | 167 days ago | IN | 0 ETH | 0.00000255 | ||||
Aggregate | 5238357 | 167 days ago | IN | 0 ETH | 0.00000178 | ||||
Aggregate | 5238314 | 167 days ago | IN | 0 ETH | 0.00000176 | ||||
Aggregate | 5237232 | 167 days ago | IN | 0 ETH | 0.0000009 | ||||
Aggregate | 5235387 | 167 days ago | IN | 0 ETH | 0.0000023 | ||||
Aggregate | 5233592 | 167 days ago | IN | 0 ETH | 0.00000314 | ||||
Aggregate | 5233514 | 167 days ago | IN | 0 ETH | 0.00000346 | ||||
Aggregate | 5233436 | 167 days ago | IN | 0 ETH | 0.00000383 | ||||
Aggregate | 5233379 | 167 days ago | IN | 0 ETH | 0.00000214 | ||||
Aggregate | 5231482 | 167 days ago | IN | 0 ETH | 0.00004137 | ||||
Aggregate | 5231385 | 167 days ago | IN | 0 ETH | 0.0000431 | ||||
Aggregate | 5231288 | 167 days ago | IN | 0 ETH | 0.00004125 | ||||
Aggregate | 5231192 | 167 days ago | IN | 0 ETH | 0.00003346 | ||||
Aggregate | 5231097 | 167 days ago | IN | 0 ETH | 0.00002858 | ||||
Aggregate | 5230995 | 167 days ago | IN | 0 ETH | 0.00002666 | ||||
Aggregate | 5230914 | 167 days ago | IN | 0 ETH | 0.00002706 |
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
1307454 | 258 days ago | Contract Creation | 0 ETH |
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 Source Code Verified (Exact Match)
Contract Name:
Dispatcher
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 200000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; // code borrowed from Multicall3 https://etherscan.io/address/0xca1167915584462449ee5b4ea51c37fe81ecdccd import { Blastable } from "./Blastable.sol"; import { Errors } from "./../libraries/Errors.sol"; import { Ownable2Step } from "./Ownable2Step.sol"; import { Multicall } from "./Multicall.sol"; import { IDispatcher } from "./../interfaces/utils/IDispatcher.sol"; /** * @title Dispatcher * @author AgentFi * @notice Dispatches function calls to multiple other contracts. * * Like an access controlled variant of Multicall3. Also allows for storing calldata for lower L1 data fee. */ contract Dispatcher is Blastable, Ownable2Step, Multicall, IDispatcher { /*************************************** STATE VARIABLES ***************************************/ mapping(address => bool) internal _isOperator; uint256 internal _storedCalldatasLength; mapping(uint256 => bytes) internal _storedCalldatas; /*************************************** CONSTRUCTOR ***************************************/ /** * @notice Constructs the BalanceFetcher contract. * @param owner_ The owner of the contract. * @param blast_ The address of the blast gas reward contract. * @param gasCollector_ The address of the gas collector. * @param blastPoints_ The address of the blast points contract. * @param pointsOperator_ The address of the blast points operator. */ constructor( address owner_, address blast_, address gasCollector_, address blastPoints_, address pointsOperator_ ) Blastable(blast_, gasCollector_, blastPoints_, pointsOperator_) { _transferOwnership(owner_); } /*************************************** AGGREGATE FUNCTIONS ***************************************/ /// @notice Backwards-compatible call aggregation with Multicall /// @param calls An array of Call structs /// @return blockNumber The block number where the calls were executed /// @return returnData An array of bytes containing the responses function aggregate(Call[] calldata calls) external payable override returns (uint256 blockNumber, bytes[] memory returnData) { _validateSenderIsOperator(); blockNumber = block.number; uint256 length = calls.length; returnData = new bytes[](length); Call calldata call; for (uint256 i = 0; i < length; ++i) { bool success; call = calls[i]; (success, returnData[i]) = call.target.call(call.callData); if(!success) revert Errors.CallFailed(); } } /// @notice Backwards-compatible with Multicall2 /// @notice Aggregate calls without requiring success /// @param requireSuccess If true, require all calls to succeed /// @param calls An array of Call structs /// @return returnData An array of Result structs function tryAggregate(bool requireSuccess, Call[] calldata calls) public payable override returns (Result[] memory returnData) { _validateSenderIsOperator(); uint256 length = calls.length; returnData = new Result[](length); Call calldata call; for (uint256 i = 0; i < length; ++i) { Result memory result = returnData[i]; call = calls[i]; (result.success, result.returnData) = call.target.call(call.callData); if(requireSuccess && !result.success) revert Errors.CallFailed(); } } /// @notice Backwards-compatible with Multicall2 /// @notice Aggregate calls and allow failures using tryAggregate /// @param calls An array of Call structs /// @return blockNumber The block number where the calls were executed /// @return blockHash The hash of the block where the calls were executed /// @return returnData An array of Result structs function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) public payable override returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) { _validateSenderIsOperator(); blockNumber = block.number; blockHash = blockhash(block.number); returnData = tryAggregate(requireSuccess, calls); } /// @notice Backwards-compatible with Multicall2 /// @notice Aggregate calls and allow failures using tryAggregate /// @param calls An array of Call structs /// @return blockNumber The block number where the calls were executed /// @return blockHash The hash of the block where the calls were executed /// @return returnData An array of Result structs function blockAndAggregate(Call[] calldata calls) external payable override returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData) { _validateSenderIsOperator(); (blockNumber, blockHash, returnData) = tryBlockAndAggregate(true, calls); } /// @notice Aggregate calls, ensuring each returns success if required /// @param calls An array of Call3 structs /// @return returnData An array of Result structs function aggregate3(Call3[] calldata calls) external payable override returns (Result[] memory returnData) { _validateSenderIsOperator(); uint256 length = calls.length; returnData = new Result[](length); Call3 calldata calli; for (uint256 i = 0; i < length; ++i) { Result memory result = returnData[i]; calli = calls[i]; (result.success, result.returnData) = calli.target.call(calli.callData); if(!calli.allowFailure && !result.success) revert Errors.CallFailed(); } } /// @notice Aggregate calls with a msg value /// @notice Reverts if msg.value is less than the sum of the call values /// @param calls An array of Call3Value structs /// @return returnData An array of Result structs function aggregate3Value(Call3Value[] calldata calls) external payable override returns (Result[] memory returnData) { _validateSenderIsOperator(); uint256 valAccumulator; uint256 length = calls.length; returnData = new Result[](length); Call3Value calldata calli; for (uint256 i = 0; i < length; ++i) { Result memory result = returnData[i]; calli = calls[i]; uint256 val = calli.value; // Humanity will be a Type V Kardashev Civilization before this overflows - andreas // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256 unchecked { valAccumulator += val; } (result.success, result.returnData) = calli.target.call{value: val}(calli.callData); if(!calli.allowFailure && !result.success) revert Errors.CallFailed(); } // Finally, make sure the msg.value = SUM(call[0...i].value) if(msg.value != valAccumulator) revert Errors.ValueMismatch(); } /*************************************** AGGREGATE AND STORE FUNCTIONS ***************************************/ /// @notice Backwards-compatible call aggregation with Multicall /// @param calls An array of Call structs /// @return blockNumber The block number where the calls were executed /// @return returnData An array of bytes containing the responses function aggregateAndStore(Call[] calldata calls) external payable override returns (uint256 blockNumber, bytes[] memory returnData, uint256[] memory calldataIDs) { _validateSenderIsOperator(); blockNumber = block.number; uint256 length = calls.length; returnData = new bytes[](length); calldataIDs = new uint256[](length); Call calldata call; for (uint256 i = 0; i < length; ++i) { bool success; call = calls[i]; (success, returnData[i]) = call.target.call(call.callData); if(!success) revert Errors.CallFailed(); calldataIDs[i] = _storeCalldata(call.callData); } } /// @notice Aggregate calls, ensuring each returns success if required /// @param calls An array of Call3 structs /// @return returnData An array of Result structs function aggregate3AndStore(Call3[] calldata calls) external payable override returns (Result[] memory returnData, uint256[] memory calldataIDs) { _validateSenderIsOperator(); uint256 length = calls.length; returnData = new Result[](length); calldataIDs = new uint256[](length); Call3 calldata calli; for (uint256 i = 0; i < length; ++i) { Result memory result = returnData[i]; calli = calls[i]; (result.success, result.returnData) = calli.target.call(calli.callData); if(!calli.allowFailure && !result.success) revert Errors.CallFailed(); calldataIDs[i] = _storeCalldata(calli.callData); } } /// @notice Aggregate calls with a msg value /// @notice Reverts if msg.value is less than the sum of the call values /// @param calls An array of Call3Value structs /// @return returnData An array of Result structs function aggregate3ValueAndStore(Call3Value[] calldata calls) external payable override returns (Result[] memory returnData, uint256[] memory calldataIDs) { _validateSenderIsOperator(); uint256 valAccumulator; uint256 length = calls.length; returnData = new Result[](length); calldataIDs = new uint256[](length); Call3Value calldata calli; for (uint256 i = 0; i < length; ++i) { Result memory result = returnData[i]; calli = calls[i]; uint256 val = calli.value; // Humanity will be a Type V Kardashev Civilization before this overflows - andreas // ~ 10^25 Wei in existence << ~ 10^76 size uint fits in a uint256 unchecked { valAccumulator += val; } (result.success, result.returnData) = calli.target.call{value: val}(calli.callData); if(!calli.allowFailure && !result.success) revert Errors.CallFailed(); calldataIDs[i] = _storeCalldata(calli.callData); } // Finally, make sure the msg.value = SUM(call[0...i].value) if(msg.value != valAccumulator) revert Errors.ValueMismatch(); } /*************************************** AGGREGATE FROM STORAGE FUNCTIONS ***************************************/ /** * @notice Calls a target using previously stored calldata. * @param target The target to call. * @param calldataID The ID of the calldata to send. * @param returnData The results. */ function aggregateFromStorage1(address target, uint256 calldataID) external payable override returns (bytes memory returnData) { _validateSenderIsOperator(); bytes memory data = _getStoredCalldata(calldataID); bool success; (success, returnData) = target.call(data); if(!success) revert Errors.CallFailed(); } /** * @notice Calls a target using previously stored calldata. * @param target The target to call. * @param calldataIDs The list of IDs of the calldatas to send. * @param returnData An array of results. */ function aggregateFromStorage2(address target, uint256[] calldata calldataIDs) external payable override returns (bytes[] memory returnData) { _validateSenderIsOperator(); uint256 length = calldataIDs.length; returnData = new bytes[](length); for (uint256 i = 0; i < length; ++i) { bytes memory data = _getStoredCalldata(calldataIDs[i]); bool success; (success, returnData[i]) = target.call(data); if(!success) revert Errors.CallFailed(); } } /** * @notice Calls a target using previously stored calldata. * @param target The target to call. * @param calls The list of calls to send. * @param returnData An array of results. */ function aggregateFromStorage3(address target, Call4[] calldata calls) external payable override returns (Result[] memory returnData) { _validateSenderIsOperator(); uint256 length = calls.length; returnData = new Result[](length); Call4 calldata calli; for (uint256 i = 0; i < length; ++i) { Result memory result = returnData[i]; calli = calls[i]; bytes memory data = _getStoredCalldata(calli.calldataID); (result.success, result.returnData) = target.call(data); if(!calli.allowFailure && !result.success) revert Errors.CallFailed(); } } /** * @notice Calls multiple targets using previously stored calldata. * @param targets The targets to call. * @param calldataID The ID of the calldata to send. * @param returnData An array of results. */ function aggregateFromStorage4(address[] calldata targets, uint256 calldataID) external payable override returns (bytes[] memory returnData) { _validateSenderIsOperator(); uint256 lengthJ = targets.length; returnData = new bytes[](lengthJ); bytes memory data = _getStoredCalldata(calldataID); for (uint256 j = 0; j < lengthJ; ++j) { bool success; (success, returnData[j]) = targets[j].call(data); if(!success) revert Errors.CallFailed(); } } /** * @notice Calls multiple targets using previously stored calldata. * @param targets The targets to call. * @param calldataIDs The list of IDs of the calldatas to send. * @param returnData An array of results. */ function aggregateFromStorage5(address[] calldata targets, uint256[] calldata calldataIDs) external payable override returns (bytes[] memory returnData) { _validateSenderIsOperator(); uint256 length = calldataIDs.length; uint256 lengthJ = targets.length; returnData = new bytes[](length*lengthJ); uint256 resultIndex = 0; for (uint256 i = 0; i < length; ++i) { bytes memory data = _getStoredCalldata(calldataIDs[i]); for (uint256 j = 0; j < lengthJ; ++j) { bool success; (success, returnData[resultIndex]) = targets[j].call(data); if(!success) revert Errors.CallFailed(); ++resultIndex; } } } /*************************************** VIEW FUNCTIONS ***************************************/ /** * @notice Returns true if the account is an operator. * @param account The account to query. * @return isAuthorized True if is an operator, false otherwise. */ function isOperator(address account) external view returns (bool isAuthorized) { isAuthorized = _isOperator[account]; } /** * @notice Returns the number of calldatas that were stored. * @return len The count. */ function storedCalldatasLength() external view returns (uint256 len) { len = _storedCalldatasLength; } /** * @notice Returns a stored calldata. * @param calldataID The ID of the calldata. * @return data The calldata stored at that index. */ function storedCalldatas(uint256 calldataID) external view returns (bytes memory data) { data = _getStoredCalldata(calldataID); } /*************************************** OWNER FUNCTIONS ***************************************/ /** * @notice Sets the status of a list of operators. * Can only be called by the contract owner. * @param params The list to set. */ function setOperators(SetOperatorParam[] calldata params) external payable override onlyOwner { for(uint256 i = 0; i < params.length; ++i) { _isOperator[params[i].account] = params[i].isAuthorized; emit OperatorSet(params[i].account, params[i].isAuthorized); } } /*************************************** HELPER FUNCTIONS ***************************************/ /** * @notice Reverts if `msg.sender` is not an operator. */ function _validateSenderIsOperator() internal view { if(!_isOperator[msg.sender]) revert Errors.NotOperator(); } /** * @notice Stores calldata. * @param data The calldata to store. * @return calldataID The index it was stored at. */ function _storeCalldata(bytes calldata data) internal returns (uint256 calldataID) { calldataID = ++_storedCalldatasLength; _storedCalldatas[calldataID] = data; emit CalldataStored(calldataID); } /** * @notice Retrieves calldata. * @param calldataID The index to retrieve from. * @return data The data that was stored. */ function _getStoredCalldata(uint256 calldataID) internal view returns (bytes memory data) { if(calldataID == 0 || calldataID > _storedCalldatasLength) revert Errors.OutOfRange(); data = _storedCalldatas[calldataID]; } }
// SPDX-License-Identifier: MIT // 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); }
// 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; import {IERC20Permit} from "../extensions/IERC20Permit.sol"; import {Address} from "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @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; } }
// SPDX-License-Identifier: MIT // 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(); } } }
// SPDX-License-Identifier: none pragma solidity 0.8.24; /** * @title IBlastable * @author AgentFi * @notice An abstract contract that configures the connection to Blast during deployment * * This involves collecting ETH yield, gas rewards, and Blast Points. ETH yield is earned by this contract automatically, while gas rewards and Blast Points are delegated to dedicated collectors. */ interface IBlastable { /** * @notice Returns the address of the Blast contract. * @return blast_ The adress of the Blast contract. */ function blast() external view returns (address blast_); /** * @notice Returns the address of the BlastPoints contract. * @return blastPoints_ The adress of the BlastPoints contract. */ function blastPoints() external view returns (address blastPoints_); }
// SPDX-License-Identifier: none pragma solidity 0.8.24; /** * @title IDispatcher * @author AgentFi * @notice Dispatches function calls to multiple other contracts. * * Like an access controlled variant of Multicall3. Also allows for storing calldata for lower L1 data fee. */ interface IDispatcher { /// @notice Emitted when an operator is added or removed. event OperatorSet(address indexed account, bool isOperator); /// @notice Emitted when calldata is stored. event CalldataStored(uint256 indexed calldataID); struct Call { address target; bytes callData; } struct Call3 { address target; bool allowFailure; bytes callData; } struct Call3Value { address target; bool allowFailure; uint256 value; bytes callData; } struct Call4 { bool allowFailure; uint256 calldataID; } struct Result { bool success; bytes returnData; } /*************************************** AGGREGATE FUNCTIONS ***************************************/ /// @notice Backwards-compatible call aggregation with Multicall /// @param calls An array of Call structs /// @return blockNumber The block number where the calls were executed /// @return returnData An array of bytes containing the responses function aggregate(Call[] calldata calls) external payable returns (uint256 blockNumber, bytes[] memory returnData); /// @notice Backwards-compatible with Multicall2 /// @notice Aggregate calls without requiring success /// @param requireSuccess If true, require all calls to succeed /// @param calls An array of Call structs /// @return returnData An array of Result structs function tryAggregate(bool requireSuccess, Call[] calldata calls) external payable returns (Result[] memory returnData); /// @notice Backwards-compatible with Multicall2 /// @notice Aggregate calls and allow failures using tryAggregate /// @param calls An array of Call structs /// @return blockNumber The block number where the calls were executed /// @return blockHash The hash of the block where the calls were executed /// @return returnData An array of Result structs function tryBlockAndAggregate(bool requireSuccess, Call[] calldata calls) external payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); /// @notice Backwards-compatible with Multicall2 /// @notice Aggregate calls and allow failures using tryAggregate /// @param calls An array of Call structs /// @return blockNumber The block number where the calls were executed /// @return blockHash The hash of the block where the calls were executed /// @return returnData An array of Result structs function blockAndAggregate(Call[] calldata calls) external payable returns (uint256 blockNumber, bytes32 blockHash, Result[] memory returnData); /// @notice Aggregate calls, ensuring each returns success if required /// @param calls An array of Call3 structs /// @return returnData An array of Result structs function aggregate3(Call3[] calldata calls) external payable returns (Result[] memory returnData); /// @notice Aggregate calls with a msg value /// @notice Reverts if msg.value is less than the sum of the call values /// @param calls An array of Call3Value structs /// @return returnData An array of Result structs function aggregate3Value(Call3Value[] calldata calls) external payable returns (Result[] memory returnData); /*************************************** AGGREGATE AND STORE FUNCTIONS ***************************************/ /// @notice Backwards-compatible call aggregation with Multicall /// @param calls An array of Call structs /// @return blockNumber The block number where the calls were executed /// @return returnData An array of bytes containing the responses function aggregateAndStore(Call[] calldata calls) external payable returns (uint256 blockNumber, bytes[] memory returnData, uint256[] memory calldataIDs); /// @notice Aggregate calls, ensuring each returns success if required /// @param calls An array of Call3 structs /// @return returnData An array of Result structs function aggregate3AndStore(Call3[] calldata calls) external payable returns (Result[] memory returnData, uint256[] memory calldataIDs); /// @notice Aggregate calls with a msg value /// @notice Reverts if msg.value is less than the sum of the call values /// @param calls An array of Call3Value structs /// @return returnData An array of Result structs function aggregate3ValueAndStore(Call3Value[] calldata calls) external payable returns (Result[] memory returnData, uint256[] memory calldataIDs); /*************************************** AGGREGATE FROM STORAGE FUNCTIONS ***************************************/ /** * @notice Calls a target using previously stored calldata. * @param target The target to call. * @param calldataID The ID of the calldata to send. * @param returnData The results. */ function aggregateFromStorage1(address target, uint256 calldataID) external payable returns (bytes memory returnData); /** * @notice Calls a target using previously stored calldata. * @param target The target to call. * @param calldataIDs The list of IDs of the calldatas to send. * @param returnData An array of results. */ function aggregateFromStorage2(address target, uint256[] calldata calldataIDs) external payable returns (bytes[] memory returnData); /** * @notice Calls a target using previously stored calldata. * @param target The target to call. * @param calls The list of calls to send. * @param returnData An array of results. */ function aggregateFromStorage3(address target, Call4[] calldata calls) external payable returns (Result[] memory returnData); /** * @notice Calls multiple targets using previously stored calldata. * @param targets The targets to call. * @param calldataID The ID of the calldata to send. * @param returnData An array of results. */ function aggregateFromStorage4(address[] calldata targets, uint256 calldataID) external payable returns (bytes[] memory returnData); /** * @notice Calls multiple targets using previously stored calldata. * @param targets The targets to call. * @param calldataIDs The list of IDs of the calldatas to send. * @param returnData An array of results. */ function aggregateFromStorage5(address[] calldata targets, uint256[] calldata calldataIDs) external payable returns (bytes[] memory returnData); /*************************************** VIEW FUNCTIONS ***************************************/ /** * @notice Returns true if the account is an operator. * @param account The account to query. * @return isAuthorized True if is an operator, false otherwise. */ function isOperator(address account) external view returns (bool isAuthorized); /** * @notice Returns the number of calldatas that were stored. * @return len The count. */ function storedCalldatasLength() external view returns (uint256 len); /** * @notice Returns a stored calldata. * @param calldataID The ID of the calldata. * @return data The calldata stored at that index. */ function storedCalldatas(uint256 calldataID) external view returns (bytes memory data); /*************************************** OWNER FUNCTIONS ***************************************/ struct SetOperatorParam { address account; bool isAuthorized; } /** * @notice Sets the status of a list of operators. * Can only be called by the contract owner. * @param params The list to set. */ function setOperators(SetOperatorParam[] calldata params) external payable; }
// SPDX-License-Identifier: none pragma solidity 0.8.24; /** * @title IMulticall * @author AgentFi * @notice Provides a function to batch together multiple calls in a single external call. */ interface IMulticall { /** * @notice Receives and executes a batch of function calls on this contract. * @param data A list of function calls to execute. * @return results The results of each function call. */ function multicall(bytes[] calldata data) external payable returns (bytes[] memory results); }
// SPDX-License-Identifier: none pragma solidity 0.8.24; /** * @title IOwnable2Step * @author AgentFi * @notice An abstract contract that provides a basic access control system through ERC173. */ interface IOwnable2Step { /*************************************** EVENTS ***************************************/ /// @notice Emitted when the contract ownership process is started. event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); /// @notice Emitted when the contract ownership process is completed. event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /*************************************** VIEW FUNCTIONS ***************************************/ /** * @notice Returns the address of the current owner. * @return owner_ The current owner. */ function owner() external view returns (address owner_); /** * @notice Returns the address of the pending owner. * @return pendingOwner_ The pending owner. */ function pendingOwner() external view returns (address pendingOwner_); /*************************************** MUTATOR FUNCTIONS ***************************************/ /** * @notice 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() external payable; /** * @notice Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. * @param newOwner The address of the new owner. */ function transferOwnership(address newOwner) external payable; /** * @notice Completes the ownership transfer of the contract to the new account. * Can only be called by the pending owner. */ function acceptOwnership() external payable; /*************************************** TOKEN BALANCE FUNCTIONS ***************************************/ /** * @notice Rescues tokens that may have been accidentally transferred in. * Can only be called by the contract owner. * @dev If the inheriting contract requires tokens in the contract, overwrite this with a revert. * @param receiver The receiver of the rescued tokens. * @param tokens The tokens to rescue. Can be ETH or ERC20s. */ function sweep(address receiver, address[] calldata tokens) external payable; }
// SPDX-License-Identifier: none pragma solidity 0.8.24; import { Errors } from "./Errors.sol"; /** * @title Calls * @author AgentFi * @notice A library for safely making low level calls. */ library Calls { /** * @notice Safely transfers the gas token using a low level `call`. * @dev If `target` reverts with a revert reason, it is bubbled up by this function. * @param target The address of the contract to `call`. * @return result The result of the function call. */ function sendValue( address target, uint256 value ) internal returns (bytes memory result) { if (address(this).balance < value) { revert Errors.InsufficientBalance(); } // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{value:value}(""); if(success) { result = 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 Errors.CallFailed(); } } } /** * @notice Safely performs a Solidity function call using a low level `call`. * @dev If `target` reverts with a revert reason, it is bubbled up by this function. * @param target The address of the contract to `delegatecall`. * @param data The data to pass to the target. * @return result The result of the function call. */ function functionCall( address target, bytes memory data ) internal returns (bytes memory result) { // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call(data); if(success) { result = 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 Errors.CallFailed(); } } } /** * @notice Safely performs a Solidity function call using a low level `call`. * @dev If `target` reverts with a revert reason, it is bubbled up by this function. * @param target The address of the contract to `delegatecall`. * @param data The data to pass to the target. * @return result The result of the function call. */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory result) { if (address(this).balance < value) { revert Errors.InsufficientBalance(); } // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{value:value}(data); if(success) { result = 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 Errors.CallFailed(); } } } /** * @notice Safely performs a Solidity function call using a low level `delegatecall`. * @dev If `target` reverts with a revert reason, it is bubbled up by this function. * @param target The address of the contract to `delegatecall`. * @param data The data to pass to the target. * @return result The result of the function call. */ function functionDelegateCall( address target, bytes memory data ) internal returns (bytes memory result) { // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); if(success) { result = 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 Errors.DelegateCallFailed(); } } } /** * @notice Verify that an address has contract code, otherwise reverts. * @param target The address to verify. */ function verifyHasCode( address target ) internal view { // checks uint256 contractSize; // solhint-disable-next-line no-inline-assembly assembly { contractSize := extcodesize(target) } if(contractSize == 0) revert Errors.NotAContract(); } }
// SPDX-License-Identifier: none pragma solidity 0.8.24; /** * @title Errors * @author AgentFi * @notice A library of custom error types used in BOOM!. */ library Errors { // call errors /// @notice Thrown when a low level call reverts without a reason. error CallFailed(); /// @notice Thrown when a low level delegatecall reverts without a reason. error DelegateCallFailed(); /// @notice Thrown if the owner tries to execute an operation that is not a call. error OnlyCallsAllowed(); /// @notice Thrown when a function should not be delegatecalled. error NoDelegateCall(); /// @notice Thrown when using an address with no code. error NotAContract(); /// @notice Thrown when a contract deployment fails. error ContractNotDeployed(); /// @notice Thrown when the sender has an insufficient balance of the token they are sending. error InsufficientBalance(); // ownership & authentication errors /// @notice Thrown when calling a function reserved for the contract owner. error NotContractOwner(); /// @notice Thrown when calling a function reserved for the pending contract owner. error NotPendingContractOwner(); /// @notice Thrown when calling a function reserved for the owner of a erc6551 account. error ERC6551InvalidSigner(); /// @notice Thrown when attempting a function reserved for the owner of the agent. error NotOwnerOfAgent(); /// @notice Thrown when a signature is invalid. error InvalidSignature(); // generic input errors /// @notice Thrown when address zero is used where it should not be. error AddressZero(); /// @notice Thrown when a nonzero address is used where the zero address is expected error AddressNotZero(); /// @notice Thrown when an address is used where it should not be. //error AddressIllegal(); /// @notice Thrown when a zero amount used where it should not be. error AmountZero(); /// @notice Thrown when the number of elements in an array is not what was expected. error LengthMismatch(); /// @notice Thrown when receiving an array of length zero. error LengthZero(); /// @notice Thrown when looking up a name that is unknown. error UnknownName(); /// @notice Thrown when accessing an element that is out of range. error OutOfRange(); /// @notice Thrown when gas token values do not match. error ValueMismatch(); /// @notice Thrown when an entry has already been registered. error AlreadyRegistered(); // execution errors /// @notice Thrown when a call reenters illegally. error ReentrancyGuard(); /// @notice Thrown when attempting to initialize a contract that has already been initialized. error AlreadyInitialized(); // nft errors /// @notice Thrown when querying an agent that does not exist. error AgentDoesNotExist(); /// @notice Thrown when transferring an agent nft to the agent account. error OwnershipCycle(); /// @notice Thrown when calling a function that is reserved for agents only. //error CallerIsNotAnAgent(); // agent creation errors /// @notice Thrown when attempting to create an agent from an account that is not whitelisted. error FactoryNotWhitelisted(); /// @notice Thrown when call a contract that has been paused. error ContractPaused(); /// @notice Thrown when using a factory and a creation settings that has been paused. error CreationSettingsPaused(); /// @notice Thrown when minting an nft over the max total supply. error OverMaxSupply(); /// @notice Thrown when minting an nft over the max public mint. error OverMaxPublicMint(); /// @notice Thrown when minting an nft but the mint has not been started. error MintNotStarted(); /// @notice Thrown when minting via the allowlist but the period has ended. error AllowlistMintEnded(); /// @notice Thrown when minting too many agents at once. error OverMaxMintPerTx(); /// @notice Thrown when minting an nft over the max allowlist mint total. error OverMaxAllowlistMintTotal(); /// @notice Thrown when minting an nft over the max allowlist mint per user. error OverMaxAllowlistMintPerAccount(); /// @notice Thrown when minting from the treasury allocation before treasury mint starts. error TreasuryMintNotStarted(); /// @notice Thrown when not paying enough to mint an nft. error InsufficientPayment(); /// @notice Thrown when minting from the treasury allocation without approval. error NotTreasuryMinter(); /// @notice Thrown when minting more agents than allowed per user. error OverMaxCreationsPerUser(); /// @notice Thrown when minting more agents than allowed per agent. error OverMaxCreationsPerAgent(); // erc2535 errors /// @notice Thrown when installing a function that is already installed. error AddFunctionDuplicate(); /// @notice Thrown when replacing a function with itself. error ReplaceFunctionSame(); /// @notice Thrown when removing a function that has not currently installed. error RemoveFunctionDoesNotExist(); /// @notice Thrown when removing a function that cannot be removed. error RemoveFunctionImmutable(); /// @notice Thrown when calling a function that does not exist in this contract. error FunctionDoesNotExist(); /// @notice Thrown when attempting to install a module that is not whitelisted. error ModuleNotWhitelisted(); // quoter errors /// @notice Thrown when failing to decode an error message. error UnknownError(); /// @notice Thrown when a revert was intentionally thrown in order to return a value. error RevertForAmount(uint256 amount); /// @notice Thrown when calling a function on a proxy that should only be called on the implementation. error NotImplementation(); /// @notice Thrown when calling a function on an implementation contract that can only be called by the gas collector. error NotGasCollector(); /// @notice Thrown when trying to mint without the minter role. error NotMinter(); /// @notice Thrown when calling the dispatcher without the operator role. error NotOperator(); // erc6551 errors error InvalidOperation(); error ContractCreationFailed(); error NotAuthorized(); error InvalidInput(); error ExceedsMaxLockTime(); error AccountLocked(); error InvalidAccountProof(); error InvalidGuardian(); error InvalidImplementation(); //error AlreadyInitialized(); error InvalidEntryPoint(); error InvalidMulticallForwarder(); error InvalidERC6551Registry(); error InvalidSender(); }
// SPDX-License-Identifier: none pragma solidity 0.8.24; import { IBlastable } from "./../interfaces/utils/IBlastable.sol"; /** * @title Blastable * @author AgentFi * @notice An abstract contract that configures the connection to Blast during deployment * * This involves collecting ETH yield, gas rewards, and Blast Points. ETH yield is earned by this contract automatically, while gas rewards and Blast Points are delegated to dedicated collectors. */ abstract contract Blastable is IBlastable { address internal immutable __blast; address internal immutable __gasCollector; address internal immutable __blastPoints; address internal immutable __pointsOperator; /** * @notice Constructs the Blastable contract. * Configures the contract to receive automatic yield, claimable gas, and assigns a gas collector. * @param blast_ The address of the blast gas reward contract. * @param gasCollector_ The address of the gas collector. * @param blastPoints_ The address of the blast points contract. * @param pointsOperator_ The address of the blast points operator. */ constructor( address blast_, address gasCollector_, address blastPoints_, address pointsOperator_ ) { __blast = blast_; __gasCollector = gasCollector_; __blastPoints = blastPoints_; __pointsOperator = pointsOperator_; // allow these calls to fail on local fork // check success after deployment blast_.call(abi.encodeWithSignature("configureAutomaticYield()")); blast_.call(abi.encodeWithSignature("configureClaimableGas()")); if(gasCollector_ != address(0)) blast_.call(abi.encodeWithSignature("configureGovernor(address)", gasCollector_)); if(pointsOperator_ != address(0)) blastPoints_.call(abi.encodeWithSignature("configurePointsOperator(address)", pointsOperator_)); } /** * @notice Returns the address of the Blast contract. * @return blast_ The adress of the Blast contract. */ function blast() public view override returns (address blast_) { blast_ = __blast; } /** * @notice Returns the address of the BlastPoints contract. * @return blastPoints_ The adress of the BlastPoints contract. */ function blastPoints() public view override returns (address blastPoints_) { blastPoints_ = __blastPoints; } /** * @notice Allows this contract to receive the gas token. */ // solhint-disable-next-line no-empty-blocks receive() external payable virtual {} }
// SPDX-License-Identifier: none pragma solidity 0.8.24; import { Calls } from "./../libraries/Calls.sol"; import { IMulticall } from "./../interfaces/utils/IMulticall.sol"; /** * @title Multicall * @author AgentFi * @notice Provides a function to batch together multiple calls in a single external call. */ abstract contract Multicall is IMulticall { /** * @notice Receives and executes a batch of function calls on this contract. * @param data A list of function calls to execute. * @return results The results of each function call. */ function multicall(bytes[] calldata data) external payable virtual returns (bytes[] memory results) { results = new bytes[](data.length); for (uint256 i = 0; i < data.length; ) { results[i] = Calls.functionDelegateCall(address(this), data[i]); unchecked { i++; } } return results; } }
// SPDX-License-Identifier: none pragma solidity 0.8.24; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import { IOwnable2Step } from "./../interfaces/utils/IOwnable2Step.sol"; import { Calls } from "./../libraries/Calls.sol"; import { Errors } from "./../libraries/Errors.sol"; /** * @title Ownable2Step * @author AgentFi * @notice An abstract contract that provides a basic access control system through ERC173. * * Based on OpenZeppelins's implementation. * * Also includes [`sweep()`](#sweep) to allow the owner to rescue any tokens that may have been sent in. */ abstract contract Ownable2Step is IOwnable2Step { /*************************************** VARIABLES ***************************************/ address private _owner; address private _pendingOwner; /** * @notice Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /*************************************** VIEW FUNCTIONS ***************************************/ /** * @notice Returns the address of the current owner. * @return owner_ The current owner. */ function owner() public view override returns (address owner_) { owner_ = _owner; } /** * @notice Returns the address of the pending owner. * @return pendingOwner_ The pending owner. */ function pendingOwner() public view override returns (address pendingOwner_) { pendingOwner_ = _pendingOwner; } /*************************************** MUTATOR FUNCTIONS ***************************************/ /** * @notice 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 payable override onlyOwner { _transferOwnership(address(0)); } /** * @notice Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. * @param newOwner The address of the new owner. */ function transferOwnership(address newOwner) public payable override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(_owner, newOwner); } /** * @notice Completes the ownership transfer of the contract to the new account. * Can only be called by the pending owner. */ function acceptOwnership() public payable override { address sender = msg.sender; if(_pendingOwner != sender) revert Errors.NotPendingContractOwner(); _transferOwnership(sender); } /*************************************** TOKEN BALANCE FUNCTIONS ***************************************/ /** * @notice Rescues tokens that may have been accidentally transferred in. * Can only be called by the contract owner. * @dev If the inheriting contract requires tokens in the contract, overwrite this with a revert. * @param receiver The receiver of the rescued tokens. * @param tokens The tokens to rescue. Can be ETH or ERC20s. */ function sweep(address receiver, address[] calldata tokens) external payable virtual override onlyOwner { for(uint256 i = 0; i < tokens.length; ++i) { address token = tokens[i]; if(token == address(0)) { Calls.sendValue(payable(receiver), address(this).balance); } else { IERC20 tkn = IERC20(token); SafeERC20.safeTransfer(tkn, receiver, tkn.balanceOf(address(this))); } } } /*************************************** HELPER FUNCTIONS ***************************************/ /** * @notice Throws if the sender is not the owner. */ function _checkOwner() internal view { if(_owner != msg.sender) revert Errors.NotContractOwner(); } /** * @notice Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal { _pendingOwner = address(0); address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
{ "optimizer": { "enabled": true, "runs": 200000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"blast_","type":"address"},{"internalType":"address","name":"gasCollector_","type":"address"},{"internalType":"address","name":"blastPoints_","type":"address"},{"internalType":"address","name":"pointsOperator_","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":[],"name":"CallFailed","type":"error"},{"inputs":[],"name":"DelegateCallFailed","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InsufficientBalance","type":"error"},{"inputs":[],"name":"NotContractOwner","type":"error"},{"inputs":[],"name":"NotOperator","type":"error"},{"inputs":[],"name":"NotPendingContractOwner","type":"error"},{"inputs":[],"name":"OutOfRange","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"ValueMismatch","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"calldataID","type":"uint256"}],"name":"CalldataStored","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isOperator","type":"bool"}],"name":"OperatorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct IDispatcher.Call[]","name":"calls","type":"tuple[]"}],"name":"aggregate","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes[]","name":"returnData","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"allowFailure","type":"bool"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct IDispatcher.Call3[]","name":"calls","type":"tuple[]"}],"name":"aggregate3","outputs":[{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"internalType":"struct IDispatcher.Result[]","name":"returnData","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"allowFailure","type":"bool"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct IDispatcher.Call3[]","name":"calls","type":"tuple[]"}],"name":"aggregate3AndStore","outputs":[{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"internalType":"struct IDispatcher.Result[]","name":"returnData","type":"tuple[]"},{"internalType":"uint256[]","name":"calldataIDs","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"allowFailure","type":"bool"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct IDispatcher.Call3Value[]","name":"calls","type":"tuple[]"}],"name":"aggregate3Value","outputs":[{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"internalType":"struct IDispatcher.Result[]","name":"returnData","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"allowFailure","type":"bool"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct IDispatcher.Call3Value[]","name":"calls","type":"tuple[]"}],"name":"aggregate3ValueAndStore","outputs":[{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"internalType":"struct IDispatcher.Result[]","name":"returnData","type":"tuple[]"},{"internalType":"uint256[]","name":"calldataIDs","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct IDispatcher.Call[]","name":"calls","type":"tuple[]"}],"name":"aggregateAndStore","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes[]","name":"returnData","type":"bytes[]"},{"internalType":"uint256[]","name":"calldataIDs","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256","name":"calldataID","type":"uint256"}],"name":"aggregateFromStorage1","outputs":[{"internalType":"bytes","name":"returnData","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"uint256[]","name":"calldataIDs","type":"uint256[]"}],"name":"aggregateFromStorage2","outputs":[{"internalType":"bytes[]","name":"returnData","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"components":[{"internalType":"bool","name":"allowFailure","type":"bool"},{"internalType":"uint256","name":"calldataID","type":"uint256"}],"internalType":"struct IDispatcher.Call4[]","name":"calls","type":"tuple[]"}],"name":"aggregateFromStorage3","outputs":[{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"internalType":"struct IDispatcher.Result[]","name":"returnData","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256","name":"calldataID","type":"uint256"}],"name":"aggregateFromStorage4","outputs":[{"internalType":"bytes[]","name":"returnData","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address[]","name":"targets","type":"address[]"},{"internalType":"uint256[]","name":"calldataIDs","type":"uint256[]"}],"name":"aggregateFromStorage5","outputs":[{"internalType":"bytes[]","name":"returnData","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"blast","outputs":[{"internalType":"address","name":"blast_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blastPoints","outputs":[{"internalType":"address","name":"blastPoints_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct IDispatcher.Call[]","name":"calls","type":"tuple[]"}],"name":"blockAndAggregate","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"internalType":"struct IDispatcher.Result[]","name":"returnData","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"isAuthorized","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"pendingOwner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isAuthorized","type":"bool"}],"internalType":"struct IDispatcher.SetOperatorParam[]","name":"params","type":"tuple[]"}],"name":"setOperators","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"calldataID","type":"uint256"}],"name":"storedCalldatas","outputs":[{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"storedCalldatasLength","outputs":[{"internalType":"uint256","name":"len","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"sweep","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bool","name":"requireSuccess","type":"bool"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct IDispatcher.Call[]","name":"calls","type":"tuple[]"}],"name":"tryAggregate","outputs":[{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"internalType":"struct IDispatcher.Result[]","name":"returnData","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bool","name":"requireSuccess","type":"bool"},{"components":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"internalType":"struct IDispatcher.Call[]","name":"calls","type":"tuple[]"}],"name":"tryBlockAndAggregate","outputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"bytes32","name":"blockHash","type":"bytes32"},{"components":[{"internalType":"bool","name":"success","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"internalType":"struct IDispatcher.Result[]","name":"returnData","type":"tuple[]"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
61010060405234801562000011575f80fd5b506040516200316038038062003160833981016040819052620000349162000338565b6001600160a01b03808516608081905281851660a05281841660c05290821660e05260408051600481526024810182526020810180516001600160e01b031663388a0bbd60e11b17905290518692869286928692916200009491620003a4565b5f604051808303815f865af19150503d805f8114620000cf576040519150601f19603f3d011682016040523d82523d5f602084013e620000d4565b606091505b505060408051600481526024810182526020810180516001600160e01b0316634e606c4760e01b17905290516001600160a01b0387169250620001189190620003a4565b5f604051808303815f865af19150503d805f811462000153576040519150601f19603f3d011682016040523d82523d5f602084013e62000158565b606091505b5050506001600160a01b03831615620001ff576040516001600160a01b03848116602483015285169060440160408051601f198184030181529181526020820180516001600160e01b0316631d70c8d360e31b17905251620001bb9190620003a4565b5f604051808303815f865af19150503d805f8114620001f6576040519150601f19603f3d011682016040523d82523d5f602084013e620001fb565b606091505b5050505b6001600160a01b03811615620002a3576040516001600160a01b03828116602483015283169060440160408051601f198184030181529181526020820180516001600160e01b03166336b91f2b60e01b179052516200025f9190620003a4565b5f604051808303815f865af19150503d805f81146200029a576040519150601f19603f3d011682016040523d82523d5f602084013e6200029f565b606091505b5050505b50505050620002b885620002c360201b60201c565b5050505050620003d2565b600180546001600160a01b03199081169091555f80546001600160a01b03848116938216841783556040519116929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b038116811462000333575f80fd5b919050565b5f805f805f60a086880312156200034d575f80fd5b62000358866200031c565b945062000368602087016200031c565b935062000378604087016200031c565b925062000388606087016200031c565b915062000398608087016200031c565b90509295509295909350565b5f82515f5b81811015620003c55760208186018101518583015201620003a9565b505f920191825250919050565b60805160a05160c05160e051612d60620004005f395f50505f6103d201525f50505f6101e90152612d605ff3fe6080604052600436106101a7575f3560e01c8063ac9650d8116100e7578063e30c397811610087578063f2fde38b11610062578063f2fde38b146104a0578063f34da092146104b3578063fe2cd1e9146104c6578063feca62c1146104d9575f80fd5b8063e30c397814610450578063e735d93f1461047a578063f2502c091461048d575f80fd5b8063bce38bd7116100c2578063bce38bd7146103f6578063c3077fa914610409578063d4372ad41461041c578063d73de43c1461043d575f80fd5b8063ac9650d814610378578063acab74b314610398578063b2bd6b50146103c4575f80fd5b8063715018a61161015257806385b53fc81161012d57806385b53fc8146103075780638a179be41461031a5780638da5cb5b1461032d578063978ee14414610356575f80fd5b8063715018a6146102e257806379ba5097146102ec57806382ad56cb146102f4575f80fd5b8063252dba4211610182578063252dba421461024b578063399542e91461026c5780636d70f7ae1461028e575f80fd5b8063174dea71146101b2578063175e1a7d146101db5780631c64885e1461022e575f80fd5b366101ae57005b5f80fd5b6101c56101c0366004612435565b6104ec565b6040516101d29190612569565b60405180910390f35b3480156101e6575f80fd5b507f00000000000000000000000000000000000000000000000000000000000000005b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b348015610239575f80fd5b506003546040519081526020016101d2565b61025e610259366004612435565b6106de565b6040516101d29291906125e4565b61027f61027a366004612611565b610854565b6040516101d293929190612662565b348015610299575f80fd5b506102d26102a83660046126b1565b73ffffffffffffffffffffffffffffffffffffffff165f9081526002602052604090205460ff1690565b60405190151581526020016101d2565b6102ea61087d565b005b6102ea610890565b6101c5610302366004612435565b6108ef565b6102ea61031536600461270b565b610a90565b6102ea61032836600461273e565b610bf2565b348015610338575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff16610209565b610369610364366004612435565b610d05565b6040516101d293929190612793565b61038b610386366004612435565b610ef3565b6040516101d291906127bd565b3480156103a3575f80fd5b506103b76103b23660046127cf565b610fdc565b6040516101d291906127e6565b3480156103cf575f80fd5b507f0000000000000000000000000000000000000000000000000000000000000000610209565b6101c5610404366004612611565b610fe7565b61027f610417366004612435565b61117d565b61042f61042a366004612435565b6111a3565b6040516101d29291906127f8565b61038b61044b36600461273e565b6113ff565b34801561045b575f80fd5b5060015473ffffffffffffffffffffffffffffffffffffffff16610209565b61038b61048836600461281c565b611555565b61042f61049b366004612435565b6116f1565b6102ea6104ae3660046126b1565b611905565b61038b6104c1366004612883565b611982565b6103b76104d43660046128cb565b611adc565b6101c56104e73660046128f3565b611b9a565b60606104f6611d23565b5f828067ffffffffffffffff81111561051157610511612935565b60405190808252806020026020018201604052801561055657816020015b604080518082019091525f81526060602082015281526020019060019003908161052f5790505b509250365f5b8281101561069b575f85828151811061057757610577612962565b6020026020010151905087878381811061059357610593612962565b90506020028101906105a5919061298f565b6040810135958601959093506105be60208501856126b1565b73ffffffffffffffffffffffffffffffffffffffff16816105e260608701876129cb565b6040516105f0929190612a2c565b5f6040518083038185875af1925050503d805f811461062a576040519150601f19603f3d011682016040523d82523d5f602084013e61062f565b606091505b50602080850191909152901515835261064e9060408601908601612a3b565b15801561065a57508151155b15610691576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505060010161055c565b508234146106d5576040517fdd8e4af700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505092915050565b5f60606106e9611d23565b439150828067ffffffffffffffff81111561070657610706612935565b60405190808252806020026020018201604052801561073957816020015b60608152602001906001900390816107245790505b509150365f5b8281101561084a575f87878381811061075a5761075a612962565b905060200281019061076c9190612a56565b925061077b60208401846126b1565b73ffffffffffffffffffffffffffffffffffffffff1661079e60208501856129cb565b6040516107ac929190612a2c565b5f604051808303815f865af19150503d805f81146107e5576040519150601f19603f3d011682016040523d82523d5f602084013e6107ea565b606091505b508684815181106107fd576107fd612962565b6020908102919091010152905080610841576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060010161073f565b5050509250929050565b5f806060610860611d23565b43925043409150610872868686610fe7565b905093509350939050565b610885611d6b565b61088e5f611dbb565b565b600154339073ffffffffffffffffffffffffffffffffffffffff1681146108e3576040517f3d6f519e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108ec81611dbb565b50565b60606108f9611d23565b818067ffffffffffffffff81111561091357610913612935565b60405190808252806020026020018201604052801561095857816020015b604080518082019091525f8152606060208201528152602001906001900390816109315790505b509150365f5b828110156106d5575f84828151811061097957610979612962565b6020026020010151905086868381811061099557610995612962565b90506020028101906109a79190612a88565b92506109b660208401846126b1565b73ffffffffffffffffffffffffffffffffffffffff166109d960408501856129cb565b6040516109e7929190612a2c565b5f604051808303815f865af19150503d805f8114610a20576040519150601f19603f3d011682016040523d82523d5f602084013e610a25565b606091505b506020808401919091529015158252610a449060408501908501612a3b565b158015610a5057508051155b15610a87576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060010161095e565b610a98611d6b565b5f5b81811015610bed57828282818110610ab457610ab4612962565b9050604002016020016020810190610acc9190612a3b565b60025f858585818110610ae157610ae1612962565b610af792602060409092020190810191506126b1565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040015f2080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055828282818110610b5b57610b5b612962565b610b7192602060409092020190810191506126b1565b73ffffffffffffffffffffffffffffffffffffffff167f1a594081ae893ab78e67d9b9e843547318164322d32c65369d78a96172d9dc8f848484818110610bba57610bba612962565b9050604002016020016020810190610bd29190612a3b565b604051901515815260200160405180910390a2600101610a9a565b505050565b610bfa611d6b565b5f5b81811015610cff575f838383818110610c1757610c17612962565b9050602002016020810190610c2c91906126b1565b905073ffffffffffffffffffffffffffffffffffffffff8116610c5957610c538547611e39565b50610cf6565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201528190610cf4908290889073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610ccb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cef9190612aba565b611f26565b505b50600101610bfc565b50505050565b5f606080610d11611d23565b439250838067ffffffffffffffff811115610d2e57610d2e612935565b604051908082528060200260200182016040528015610d6157816020015b6060815260200190600190039081610d4c5790505b5092508067ffffffffffffffff811115610d7d57610d7d612935565b604051908082528060200260200182016040528015610da6578160200160208202803683370190505b509150365f5b82811015610ee9575f888883818110610dc757610dc7612962565b9050602002810190610dd99190612a56565b9250610de860208401846126b1565b73ffffffffffffffffffffffffffffffffffffffff16610e0b60208501856129cb565b604051610e19929190612a2c565b5f604051808303815f865af19150503d805f8114610e52576040519150601f19603f3d011682016040523d82523d5f602084013e610e57565b606091505b50878481518110610e6a57610e6a612962565b6020908102919091010152905080610eae576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ec3610ebe60208501856129cb565b611fb3565b858381518110610ed557610ed5612962565b602090810291909101015250600101610dac565b5050509250925092565b60608167ffffffffffffffff811115610f0e57610f0e612935565b604051908082528060200260200182016040528015610f4157816020015b6060815260200190600190039081610f2c5790505b5090505f5b82811015610fd457610faf30858584818110610f6457610f64612962565b9050602002810190610f7691906129cb565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061201392505050565b828281518110610fc157610fc1612962565b6020908102919091010152600101610f46565b505b92915050565b6060610fd6826120ce565b6060610ff1611d23565b818067ffffffffffffffff81111561100b5761100b612935565b60405190808252806020026020018201604052801561105057816020015b604080518082019091525f8152606060208201528152602001906001900390816110295790505b509150365f5b82811015611173575f84828151811061107157611071612962565b6020026020010151905086868381811061108d5761108d612962565b905060200281019061109f9190612a56565b92506110ae60208401846126b1565b73ffffffffffffffffffffffffffffffffffffffff166110d160208501856129cb565b6040516110df929190612a2c565b5f604051808303815f865af19150503d805f8114611118576040519150601f19603f3d011682016040523d82523d5f602084013e61111d565b606091505b5060208301521515815287801561113357508051155b1561116a576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101611056565b5050509392505050565b5f806060611189611d23565b61119560018686610854565b919790965090945092505050565b6060806111ae611d23565b5f838067ffffffffffffffff8111156111c9576111c9612935565b60405190808252806020026020018201604052801561120e57816020015b604080518082019091525f8152606060208201528152602001906001900390816111e75790505b5093508067ffffffffffffffff81111561122a5761122a612935565b604051908082528060200260200182016040528015611253578160200160208202803683370190505b509250365f5b828110156113c5575f86828151811061127457611274612962565b6020026020010151905088888381811061129057611290612962565b90506020028101906112a2919061298f565b6040810135958601959093506112bb60208501856126b1565b73ffffffffffffffffffffffffffffffffffffffff16816112df60608701876129cb565b6040516112ed929190612a2c565b5f6040518083038185875af1925050503d805f8114611327576040519150601f19603f3d011682016040523d82523d5f602084013e61132c565b606091505b50602080850191909152901515835261134b9060408601908601612a3b565b15801561135757508151155b1561138e576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61139e610ebe60608601866129cb565b8784815181106113b0576113b0612962565b60209081029190910101525050600101611259565b5082341461084a576040517fdd8e4af700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6060611409611d23565b818067ffffffffffffffff81111561142357611423612935565b60405190808252806020026020018201604052801561145657816020015b60608152602001906001900390816114415790505b5091505f5b8181101561154c575f61148586868481811061147957611479612962565b905060200201356120ce565b90505f8773ffffffffffffffffffffffffffffffffffffffff16826040516114ad9190612ad1565b5f604051808303815f865af19150503d805f81146114e6576040519150601f19603f3d011682016040523d82523d5f602084013e6114eb565b606091505b508685815181106114fe576114fe612962565b6020908102919091010152905080611542576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505060010161145b565b50509392505050565b606061155f611d23565b818461156b8183612b0f565b67ffffffffffffffff81111561158357611583612935565b6040519080825280602002602001820160405280156115b657816020015b60608152602001906001900390816115a15790505b5092505f805b838110156116e5575f6115da88888481811061147957611479612962565b90505f5b848110156116db575f8b8b838181106115f9576115f9612962565b905060200201602081019061160e91906126b1565b73ffffffffffffffffffffffffffffffffffffffff16836040516116329190612ad1565b5f604051808303815f865af19150503d805f811461166b576040519150601f19603f3d011682016040523d82523d5f602084013e611670565b606091505b5089878151811061168357611683612962565b60209081029190910101529050806116c7576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d085612b26565b9450506001016115de565b50506001016115bc565b50505050949350505050565b6060806116fc611d23565b828067ffffffffffffffff81111561171657611716612935565b60405190808252806020026020018201604052801561175b57816020015b604080518082019091525f8152606060208201528152602001906001900390816117345790505b5092508067ffffffffffffffff81111561177757611777612935565b6040519080825280602002602001820160405280156117a0578160200160208202803683370190505b509150365f5b8281101561084a575f8582815181106117c1576117c1612962565b602002602001015190508787838181106117dd576117dd612962565b90506020028101906117ef9190612a88565b92506117fe60208401846126b1565b73ffffffffffffffffffffffffffffffffffffffff1661182160408501856129cb565b60405161182f929190612a2c565b5f604051808303815f865af19150503d805f8114611868576040519150601f19603f3d011682016040523d82523d5f602084013e61186d565b606091505b50602080840191909152901515825261188c9060408501908501612a3b565b15801561189857508051155b156118cf576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118df610ebe60408501856129cb565b8583815181106118f1576118f1612962565b6020908102919091010152506001016117a6565b61190d611d6b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092555f8054604051929316917f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227009190a350565b606061198c611d23565b828067ffffffffffffffff8111156119a6576119a6612935565b6040519080825280602002602001820160405280156119d957816020015b60608152602001906001900390816119c45790505b5091505f6119e6846120ce565b90505f5b82811015611173575f878783818110611a0557611a05612962565b9050602002016020810190611a1a91906126b1565b73ffffffffffffffffffffffffffffffffffffffff1683604051611a3e9190612ad1565b5f604051808303815f865af19150503d805f8114611a77576040519150601f19603f3d011682016040523d82523d5f602084013e611a7c565b606091505b50868481518110611a8f57611a8f612962565b6020908102919091010152905080611ad3576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001016119ea565b6060611ae6611d23565b5f611af0836120ce565b90505f8473ffffffffffffffffffffffffffffffffffffffff1682604051611b189190612ad1565b5f604051808303815f865af19150503d805f8114611b51576040519150601f19603f3d011682016040523d82523d5f602084013e611b56565b606091505b509350905080611b92576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505092915050565b6060611ba4611d23565b818067ffffffffffffffff811115611bbe57611bbe612935565b604051908082528060200260200182016040528015611c0357816020015b604080518082019091525f815260606020820152815260200190600190039081611bdc5790505b509150365f5b82811015611173575f848281518110611c2457611c24612962565b60200260200101519050868683818110611c4057611c40612962565b90506040020192505f611c5684602001356120ce565b90508873ffffffffffffffffffffffffffffffffffffffff1681604051611c7d9190612ad1565b5f604051808303815f865af19150503d805f8114611cb6576040519150601f19603f3d011682016040523d82523d5f602084013e611cbb565b606091505b506020808501919091529015158352611cd690850185612a3b565b158015611ce257508151155b15611d19576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600101611c09565b335f9081526002602052604090205460ff1661088e576040517f7c214f0400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5473ffffffffffffffffffffffffffffffffffffffff16331461088e576040517fbfcafd3700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000009081169091555f805473ffffffffffffffffffffffffffffffffffffffff848116938216841783556040519116929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606081471015611e75576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f808473ffffffffffffffffffffffffffffffffffffffff16846040515f6040518083038185875af1925050503d805f8114611ecc576040519150601f19603f3d011682016040523d82523d5f602084013e611ed1565b606091505b50915091508115611ee457809250611b92565b805115611ef45780518082602001fd5b6040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610bed9084906121b0565b5f60035f8154611fc290612b26565b91829055505f818152600460205260409020909150611fe2838583612bf9565b5060405181907ff661784363d7a71555ff998d17aa067de17bdc863e71c04f367097aa35e81fc3905f90a292915050565b60605f808473ffffffffffffffffffffffffffffffffffffffff168460405161203c9190612ad1565b5f60405180830381855af49150503d805f8114612074576040519150601f19603f3d011682016040523d82523d5f602084013e612079565b606091505b5091509150811561208c57809250611b92565b80511561209c5780518082602001fd5b6040517f18cecad500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608115806120de575060035482115b15612115576040517f7db3aba700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f828152600460205260409020805461212d90612b5d565b80601f016020809104026020016040519081016040528092919081815260200182805461215990612b5d565b80156121a45780601f1061217b576101008083540402835291602001916121a4565b820191905f5260205f20905b81548152906001019060200180831161218757829003601f168201915b50505050509050919050565b5f6121d173ffffffffffffffffffffffffffffffffffffffff841683612249565b905080515f141580156121f55750808060200190518101906121f39190612d0f565b155b15610bed576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024015b60405180910390fd5b606061225683835f61225d565b9392505050565b60608147101561229b576040517fcd786059000000000000000000000000000000000000000000000000000000008152306004820152602401612240565b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516122c39190612ad1565b5f6040518083038185875af1925050503d805f81146122fd576040519150601f19603f3d011682016040523d82523d5f602084013e612302565b606091505b509150915061231286838361231c565b9695505050505050565b6060826123315761232c826123ab565b612256565b8151158015612355575073ffffffffffffffffffffffffffffffffffffffff84163b155b156123a4576040517f9996b31500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401612240565b5080612256565b8051156123bb5780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8083601f8401126123fd575f80fd5b50813567ffffffffffffffff811115612414575f80fd5b6020830191508360208260051b850101111561242e575f80fd5b9250929050565b5f8060208385031215612446575f80fd5b823567ffffffffffffffff81111561245c575f80fd5b612468858286016123ed565b90969095509350505050565b5f5b8381101561248e578181015183820152602001612476565b50505f910152565b5f81518084526124ad816020860160208601612474565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b5f82825180855260208086019550808260051b8401018186015f5b8481101561255c578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00189528151805115158452840151604085850181905261254881860183612496565b9a86019a94505050908301906001016124fa565b5090979650505050505050565b602081525f61225660208301846124df565b5f8282518085526020808601955060208260051b840101602086015f5b8481101561255c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189526125d2838351612496565b98840198925090830190600101612598565b828152604060208201525f6125fc604083018461257b565b949350505050565b80151581146108ec575f80fd5b5f805f60408486031215612623575f80fd5b833561262e81612604565b9250602084013567ffffffffffffffff811115612649575f80fd5b612655868287016123ed565b9497909650939450505050565b838152826020820152606060408201525f61268060608301846124df565b95945050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146126ac575f80fd5b919050565b5f602082840312156126c1575f80fd5b61225682612689565b5f8083601f8401126126da575f80fd5b50813567ffffffffffffffff8111156126f1575f80fd5b6020830191508360208260061b850101111561242e575f80fd5b5f806020838503121561271c575f80fd5b823567ffffffffffffffff811115612732575f80fd5b612468858286016126ca565b5f805f60408486031215612750575f80fd5b61262e84612689565b5f815180845260208085019450602084015f5b838110156127885781518752958201959082019060010161276c565b509495945050505050565b838152606060208201525f6127ab606083018561257b565b82810360408401526123128185612759565b602081525f612256602083018461257b565b5f602082840312156127df575f80fd5b5035919050565b602081525f6122566020830184612496565b604081525f61280a60408301856124df565b82810360208401526126808185612759565b5f805f806040858703121561282f575f80fd5b843567ffffffffffffffff80821115612846575f80fd5b612852888389016123ed565b9096509450602087013591508082111561286a575f80fd5b50612877878288016123ed565b95989497509550505050565b5f805f60408486031215612895575f80fd5b833567ffffffffffffffff8111156128ab575f80fd5b6128b7868287016123ed565b909790965060209590950135949350505050565b5f80604083850312156128dc575f80fd5b6128e583612689565b946020939093013593505050565b5f805f60408486031215612905575f80fd5b61290e84612689565b9250602084013567ffffffffffffffff811115612929575f80fd5b612655868287016126ca565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126129c1575f80fd5b9190910192915050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126129fe575f80fd5b83018035915067ffffffffffffffff821115612a18575f80fd5b60200191503681900382131561242e575f80fd5b818382375f9101908152919050565b5f60208284031215612a4b575f80fd5b813561225681612604565b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126129c1575f80fd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126129c1575f80fd5b5f60208284031215612aca575f80fd5b5051919050565b5f82516129c1818460208701612474565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8082028115828204841417610fd657610fd6612ae2565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612b5657612b56612ae2565b5060010190565b600181811c90821680612b7157607f821691505b602082108103612ba8577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b601f821115610bed57805f5260205f20601f840160051c81016020851015612bd35750805b601f840160051c820191505b81811015612bf2575f8155600101612bdf565b5050505050565b67ffffffffffffffff831115612c1157612c11612935565b612c2583612c1f8354612b5d565b83612bae565b5f601f841160018114612c75575f8515612c3f5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355612bf2565b5f838152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08716915b82811015612cc25786850135825560209485019460019092019101612ca2565b5086821015612cfd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f60208284031215612d1f575f80fd5b81516122568161260456fea2646970667358221220989eaa7e4bcd93bb65f2efef03acb1538728171421a635f02e3693d52e04ee2064736f6c63430008180033000000000000000000000000a214a4fc09c42202c404e2976c50373fe5f5b7890000000000000000000000004300000000000000000000000000000000000002000000000000000000000000f237c20584daca970498917470864f4d027de4ca0000000000000000000000002536fe9ab3f511540f2f9e2ec2a805005c3dd800000000000000000000000000454c0c1cf7be9341d82ce0f16979b8689ed4aad0
Deployed Bytecode
0x6080604052600436106101a7575f3560e01c8063ac9650d8116100e7578063e30c397811610087578063f2fde38b11610062578063f2fde38b146104a0578063f34da092146104b3578063fe2cd1e9146104c6578063feca62c1146104d9575f80fd5b8063e30c397814610450578063e735d93f1461047a578063f2502c091461048d575f80fd5b8063bce38bd7116100c2578063bce38bd7146103f6578063c3077fa914610409578063d4372ad41461041c578063d73de43c1461043d575f80fd5b8063ac9650d814610378578063acab74b314610398578063b2bd6b50146103c4575f80fd5b8063715018a61161015257806385b53fc81161012d57806385b53fc8146103075780638a179be41461031a5780638da5cb5b1461032d578063978ee14414610356575f80fd5b8063715018a6146102e257806379ba5097146102ec57806382ad56cb146102f4575f80fd5b8063252dba4211610182578063252dba421461024b578063399542e91461026c5780636d70f7ae1461028e575f80fd5b8063174dea71146101b2578063175e1a7d146101db5780631c64885e1461022e575f80fd5b366101ae57005b5f80fd5b6101c56101c0366004612435565b6104ec565b6040516101d29190612569565b60405180910390f35b3480156101e6575f80fd5b507f00000000000000000000000043000000000000000000000000000000000000025b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101d2565b348015610239575f80fd5b506003546040519081526020016101d2565b61025e610259366004612435565b6106de565b6040516101d29291906125e4565b61027f61027a366004612611565b610854565b6040516101d293929190612662565b348015610299575f80fd5b506102d26102a83660046126b1565b73ffffffffffffffffffffffffffffffffffffffff165f9081526002602052604090205460ff1690565b60405190151581526020016101d2565b6102ea61087d565b005b6102ea610890565b6101c5610302366004612435565b6108ef565b6102ea61031536600461270b565b610a90565b6102ea61032836600461273e565b610bf2565b348015610338575f80fd5b505f5473ffffffffffffffffffffffffffffffffffffffff16610209565b610369610364366004612435565b610d05565b6040516101d293929190612793565b61038b610386366004612435565b610ef3565b6040516101d291906127bd565b3480156103a3575f80fd5b506103b76103b23660046127cf565b610fdc565b6040516101d291906127e6565b3480156103cf575f80fd5b507f0000000000000000000000002536fe9ab3f511540f2f9e2ec2a805005c3dd800610209565b6101c5610404366004612611565b610fe7565b61027f610417366004612435565b61117d565b61042f61042a366004612435565b6111a3565b6040516101d29291906127f8565b61038b61044b36600461273e565b6113ff565b34801561045b575f80fd5b5060015473ffffffffffffffffffffffffffffffffffffffff16610209565b61038b61048836600461281c565b611555565b61042f61049b366004612435565b6116f1565b6102ea6104ae3660046126b1565b611905565b61038b6104c1366004612883565b611982565b6103b76104d43660046128cb565b611adc565b6101c56104e73660046128f3565b611b9a565b60606104f6611d23565b5f828067ffffffffffffffff81111561051157610511612935565b60405190808252806020026020018201604052801561055657816020015b604080518082019091525f81526060602082015281526020019060019003908161052f5790505b509250365f5b8281101561069b575f85828151811061057757610577612962565b6020026020010151905087878381811061059357610593612962565b90506020028101906105a5919061298f565b6040810135958601959093506105be60208501856126b1565b73ffffffffffffffffffffffffffffffffffffffff16816105e260608701876129cb565b6040516105f0929190612a2c565b5f6040518083038185875af1925050503d805f811461062a576040519150601f19603f3d011682016040523d82523d5f602084013e61062f565b606091505b50602080850191909152901515835261064e9060408601908601612a3b565b15801561065a57508151155b15610691576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505060010161055c565b508234146106d5576040517fdd8e4af700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50505092915050565b5f60606106e9611d23565b439150828067ffffffffffffffff81111561070657610706612935565b60405190808252806020026020018201604052801561073957816020015b60608152602001906001900390816107245790505b509150365f5b8281101561084a575f87878381811061075a5761075a612962565b905060200281019061076c9190612a56565b925061077b60208401846126b1565b73ffffffffffffffffffffffffffffffffffffffff1661079e60208501856129cb565b6040516107ac929190612a2c565b5f604051808303815f865af19150503d805f81146107e5576040519150601f19603f3d011682016040523d82523d5f602084013e6107ea565b606091505b508684815181106107fd576107fd612962565b6020908102919091010152905080610841576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060010161073f565b5050509250929050565b5f806060610860611d23565b43925043409150610872868686610fe7565b905093509350939050565b610885611d6b565b61088e5f611dbb565b565b600154339073ffffffffffffffffffffffffffffffffffffffff1681146108e3576040517f3d6f519e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108ec81611dbb565b50565b60606108f9611d23565b818067ffffffffffffffff81111561091357610913612935565b60405190808252806020026020018201604052801561095857816020015b604080518082019091525f8152606060208201528152602001906001900390816109315790505b509150365f5b828110156106d5575f84828151811061097957610979612962565b6020026020010151905086868381811061099557610995612962565b90506020028101906109a79190612a88565b92506109b660208401846126b1565b73ffffffffffffffffffffffffffffffffffffffff166109d960408501856129cb565b6040516109e7929190612a2c565b5f604051808303815f865af19150503d805f8114610a20576040519150601f19603f3d011682016040523d82523d5f602084013e610a25565b606091505b506020808401919091529015158252610a449060408501908501612a3b565b158015610a5057508051155b15610a87576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060010161095e565b610a98611d6b565b5f5b81811015610bed57828282818110610ab457610ab4612962565b9050604002016020016020810190610acc9190612a3b565b60025f858585818110610ae157610ae1612962565b610af792602060409092020190810191506126b1565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040015f2080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055828282818110610b5b57610b5b612962565b610b7192602060409092020190810191506126b1565b73ffffffffffffffffffffffffffffffffffffffff167f1a594081ae893ab78e67d9b9e843547318164322d32c65369d78a96172d9dc8f848484818110610bba57610bba612962565b9050604002016020016020810190610bd29190612a3b565b604051901515815260200160405180910390a2600101610a9a565b505050565b610bfa611d6b565b5f5b81811015610cff575f838383818110610c1757610c17612962565b9050602002016020810190610c2c91906126b1565b905073ffffffffffffffffffffffffffffffffffffffff8116610c5957610c538547611e39565b50610cf6565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201528190610cf4908290889073ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015610ccb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cef9190612aba565b611f26565b505b50600101610bfc565b50505050565b5f606080610d11611d23565b439250838067ffffffffffffffff811115610d2e57610d2e612935565b604051908082528060200260200182016040528015610d6157816020015b6060815260200190600190039081610d4c5790505b5092508067ffffffffffffffff811115610d7d57610d7d612935565b604051908082528060200260200182016040528015610da6578160200160208202803683370190505b509150365f5b82811015610ee9575f888883818110610dc757610dc7612962565b9050602002810190610dd99190612a56565b9250610de860208401846126b1565b73ffffffffffffffffffffffffffffffffffffffff16610e0b60208501856129cb565b604051610e19929190612a2c565b5f604051808303815f865af19150503d805f8114610e52576040519150601f19603f3d011682016040523d82523d5f602084013e610e57565b606091505b50878481518110610e6a57610e6a612962565b6020908102919091010152905080610eae576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ec3610ebe60208501856129cb565b611fb3565b858381518110610ed557610ed5612962565b602090810291909101015250600101610dac565b5050509250925092565b60608167ffffffffffffffff811115610f0e57610f0e612935565b604051908082528060200260200182016040528015610f4157816020015b6060815260200190600190039081610f2c5790505b5090505f5b82811015610fd457610faf30858584818110610f6457610f64612962565b9050602002810190610f7691906129cb565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061201392505050565b828281518110610fc157610fc1612962565b6020908102919091010152600101610f46565b505b92915050565b6060610fd6826120ce565b6060610ff1611d23565b818067ffffffffffffffff81111561100b5761100b612935565b60405190808252806020026020018201604052801561105057816020015b604080518082019091525f8152606060208201528152602001906001900390816110295790505b509150365f5b82811015611173575f84828151811061107157611071612962565b6020026020010151905086868381811061108d5761108d612962565b905060200281019061109f9190612a56565b92506110ae60208401846126b1565b73ffffffffffffffffffffffffffffffffffffffff166110d160208501856129cb565b6040516110df929190612a2c565b5f604051808303815f865af19150503d805f8114611118576040519150601f19603f3d011682016040523d82523d5f602084013e61111d565b606091505b5060208301521515815287801561113357508051155b1561116a576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50600101611056565b5050509392505050565b5f806060611189611d23565b61119560018686610854565b919790965090945092505050565b6060806111ae611d23565b5f838067ffffffffffffffff8111156111c9576111c9612935565b60405190808252806020026020018201604052801561120e57816020015b604080518082019091525f8152606060208201528152602001906001900390816111e75790505b5093508067ffffffffffffffff81111561122a5761122a612935565b604051908082528060200260200182016040528015611253578160200160208202803683370190505b509250365f5b828110156113c5575f86828151811061127457611274612962565b6020026020010151905088888381811061129057611290612962565b90506020028101906112a2919061298f565b6040810135958601959093506112bb60208501856126b1565b73ffffffffffffffffffffffffffffffffffffffff16816112df60608701876129cb565b6040516112ed929190612a2c565b5f6040518083038185875af1925050503d805f8114611327576040519150601f19603f3d011682016040523d82523d5f602084013e61132c565b606091505b50602080850191909152901515835261134b9060408601908601612a3b565b15801561135757508151155b1561138e576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61139e610ebe60608601866129cb565b8784815181106113b0576113b0612962565b60209081029190910101525050600101611259565b5082341461084a576040517fdd8e4af700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6060611409611d23565b818067ffffffffffffffff81111561142357611423612935565b60405190808252806020026020018201604052801561145657816020015b60608152602001906001900390816114415790505b5091505f5b8181101561154c575f61148586868481811061147957611479612962565b905060200201356120ce565b90505f8773ffffffffffffffffffffffffffffffffffffffff16826040516114ad9190612ad1565b5f604051808303815f865af19150503d805f81146114e6576040519150601f19603f3d011682016040523d82523d5f602084013e6114eb565b606091505b508685815181106114fe576114fe612962565b6020908102919091010152905080611542576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505060010161145b565b50509392505050565b606061155f611d23565b818461156b8183612b0f565b67ffffffffffffffff81111561158357611583612935565b6040519080825280602002602001820160405280156115b657816020015b60608152602001906001900390816115a15790505b5092505f805b838110156116e5575f6115da88888481811061147957611479612962565b90505f5b848110156116db575f8b8b838181106115f9576115f9612962565b905060200201602081019061160e91906126b1565b73ffffffffffffffffffffffffffffffffffffffff16836040516116329190612ad1565b5f604051808303815f865af19150503d805f811461166b576040519150601f19603f3d011682016040523d82523d5f602084013e611670565b606091505b5089878151811061168357611683612962565b60209081029190910101529050806116c7576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116d085612b26565b9450506001016115de565b50506001016115bc565b50505050949350505050565b6060806116fc611d23565b828067ffffffffffffffff81111561171657611716612935565b60405190808252806020026020018201604052801561175b57816020015b604080518082019091525f8152606060208201528152602001906001900390816117345790505b5092508067ffffffffffffffff81111561177757611777612935565b6040519080825280602002602001820160405280156117a0578160200160208202803683370190505b509150365f5b8281101561084a575f8582815181106117c1576117c1612962565b602002602001015190508787838181106117dd576117dd612962565b90506020028101906117ef9190612a88565b92506117fe60208401846126b1565b73ffffffffffffffffffffffffffffffffffffffff1661182160408501856129cb565b60405161182f929190612a2c565b5f604051808303815f865af19150503d805f8114611868576040519150601f19603f3d011682016040523d82523d5f602084013e61186d565b606091505b50602080840191909152901515825261188c9060408501908501612a3b565b15801561189857508051155b156118cf576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6118df610ebe60408501856129cb565b8583815181106118f1576118f1612962565b6020908102919091010152506001016117a6565b61190d611d6b565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8381169182179092555f8054604051929316917f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e227009190a350565b606061198c611d23565b828067ffffffffffffffff8111156119a6576119a6612935565b6040519080825280602002602001820160405280156119d957816020015b60608152602001906001900390816119c45790505b5091505f6119e6846120ce565b90505f5b82811015611173575f878783818110611a0557611a05612962565b9050602002016020810190611a1a91906126b1565b73ffffffffffffffffffffffffffffffffffffffff1683604051611a3e9190612ad1565b5f604051808303815f865af19150503d805f8114611a77576040519150601f19603f3d011682016040523d82523d5f602084013e611a7c565b606091505b50868481518110611a8f57611a8f612962565b6020908102919091010152905080611ad3576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001016119ea565b6060611ae6611d23565b5f611af0836120ce565b90505f8473ffffffffffffffffffffffffffffffffffffffff1682604051611b189190612ad1565b5f604051808303815f865af19150503d805f8114611b51576040519150601f19603f3d011682016040523d82523d5f602084013e611b56565b606091505b509350905080611b92576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505092915050565b6060611ba4611d23565b818067ffffffffffffffff811115611bbe57611bbe612935565b604051908082528060200260200182016040528015611c0357816020015b604080518082019091525f815260606020820152815260200190600190039081611bdc5790505b509150365f5b82811015611173575f848281518110611c2457611c24612962565b60200260200101519050868683818110611c4057611c40612962565b90506040020192505f611c5684602001356120ce565b90508873ffffffffffffffffffffffffffffffffffffffff1681604051611c7d9190612ad1565b5f604051808303815f865af19150503d805f8114611cb6576040519150601f19603f3d011682016040523d82523d5f602084013e611cbb565b606091505b506020808501919091529015158352611cd690850185612a3b565b158015611ce257508151155b15611d19576040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050600101611c09565b335f9081526002602052604090205460ff1661088e576040517f7c214f0400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5473ffffffffffffffffffffffffffffffffffffffff16331461088e576040517fbfcafd3700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000009081169091555f805473ffffffffffffffffffffffffffffffffffffffff848116938216841783556040519116929183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b606081471015611e75576040517ff4d678b800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f808473ffffffffffffffffffffffffffffffffffffffff16846040515f6040518083038185875af1925050503d805f8114611ecc576040519150601f19603f3d011682016040523d82523d5f602084013e611ed1565b606091505b50915091508115611ee457809250611b92565b805115611ef45780518082602001fd5b6040517f3204506f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805173ffffffffffffffffffffffffffffffffffffffff8416602482015260448082018490528251808303909101815260649091019091526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052610bed9084906121b0565b5f60035f8154611fc290612b26565b91829055505f818152600460205260409020909150611fe2838583612bf9565b5060405181907ff661784363d7a71555ff998d17aa067de17bdc863e71c04f367097aa35e81fc3905f90a292915050565b60605f808473ffffffffffffffffffffffffffffffffffffffff168460405161203c9190612ad1565b5f60405180830381855af49150503d805f8114612074576040519150601f19603f3d011682016040523d82523d5f602084013e612079565b606091505b5091509150811561208c57809250611b92565b80511561209c5780518082602001fd5b6040517f18cecad500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60608115806120de575060035482115b15612115576040517f7db3aba700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f828152600460205260409020805461212d90612b5d565b80601f016020809104026020016040519081016040528092919081815260200182805461215990612b5d565b80156121a45780601f1061217b576101008083540402835291602001916121a4565b820191905f5260205f20905b81548152906001019060200180831161218757829003601f168201915b50505050509050919050565b5f6121d173ffffffffffffffffffffffffffffffffffffffff841683612249565b905080515f141580156121f55750808060200190518101906121f39190612d0f565b155b15610bed576040517f5274afe700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841660048201526024015b60405180910390fd5b606061225683835f61225d565b9392505050565b60608147101561229b576040517fcd786059000000000000000000000000000000000000000000000000000000008152306004820152602401612240565b5f808573ffffffffffffffffffffffffffffffffffffffff1684866040516122c39190612ad1565b5f6040518083038185875af1925050503d805f81146122fd576040519150601f19603f3d011682016040523d82523d5f602084013e612302565b606091505b509150915061231286838361231c565b9695505050505050565b6060826123315761232c826123ab565b612256565b8151158015612355575073ffffffffffffffffffffffffffffffffffffffff84163b155b156123a4576040517f9996b31500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85166004820152602401612240565b5080612256565b8051156123bb5780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8083601f8401126123fd575f80fd5b50813567ffffffffffffffff811115612414575f80fd5b6020830191508360208260051b850101111561242e575f80fd5b9250929050565b5f8060208385031215612446575f80fd5b823567ffffffffffffffff81111561245c575f80fd5b612468858286016123ed565b90969095509350505050565b5f5b8381101561248e578181015183820152602001612476565b50505f910152565b5f81518084526124ad816020860160208601612474565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b5f82825180855260208086019550808260051b8401018186015f5b8481101561255c578583037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00189528151805115158452840151604085850181905261254881860183612496565b9a86019a94505050908301906001016124fa565b5090979650505050505050565b602081525f61225660208301846124df565b5f8282518085526020808601955060208260051b840101602086015f5b8481101561255c577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08684030189526125d2838351612496565b98840198925090830190600101612598565b828152604060208201525f6125fc604083018461257b565b949350505050565b80151581146108ec575f80fd5b5f805f60408486031215612623575f80fd5b833561262e81612604565b9250602084013567ffffffffffffffff811115612649575f80fd5b612655868287016123ed565b9497909650939450505050565b838152826020820152606060408201525f61268060608301846124df565b95945050505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146126ac575f80fd5b919050565b5f602082840312156126c1575f80fd5b61225682612689565b5f8083601f8401126126da575f80fd5b50813567ffffffffffffffff8111156126f1575f80fd5b6020830191508360208260061b850101111561242e575f80fd5b5f806020838503121561271c575f80fd5b823567ffffffffffffffff811115612732575f80fd5b612468858286016126ca565b5f805f60408486031215612750575f80fd5b61262e84612689565b5f815180845260208085019450602084015f5b838110156127885781518752958201959082019060010161276c565b509495945050505050565b838152606060208201525f6127ab606083018561257b565b82810360408401526123128185612759565b602081525f612256602083018461257b565b5f602082840312156127df575f80fd5b5035919050565b602081525f6122566020830184612496565b604081525f61280a60408301856124df565b82810360208401526126808185612759565b5f805f806040858703121561282f575f80fd5b843567ffffffffffffffff80821115612846575f80fd5b612852888389016123ed565b9096509450602087013591508082111561286a575f80fd5b50612877878288016123ed565b95989497509550505050565b5f805f60408486031215612895575f80fd5b833567ffffffffffffffff8111156128ab575f80fd5b6128b7868287016123ed565b909790965060209590950135949350505050565b5f80604083850312156128dc575f80fd5b6128e583612689565b946020939093013593505050565b5f805f60408486031215612905575f80fd5b61290e84612689565b9250602084013567ffffffffffffffff811115612929575f80fd5b612655868287016126ca565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126129c1575f80fd5b9190910192915050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126129fe575f80fd5b83018035915067ffffffffffffffff821115612a18575f80fd5b60200191503681900382131561242e575f80fd5b818382375f9101908152919050565b5f60208284031215612a4b575f80fd5b813561225681612604565b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc18336030181126129c1575f80fd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa18336030181126129c1575f80fd5b5f60208284031215612aca575f80fd5b5051919050565b5f82516129c1818460208701612474565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8082028115828204841417610fd657610fd6612ae2565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612b5657612b56612ae2565b5060010190565b600181811c90821680612b7157607f821691505b602082108103612ba8577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b601f821115610bed57805f5260205f20601f840160051c81016020851015612bd35750805b601f840160051c820191505b81811015612bf2575f8155600101612bdf565b5050505050565b67ffffffffffffffff831115612c1157612c11612935565b612c2583612c1f8354612b5d565b83612bae565b5f601f841160018114612c75575f8515612c3f5750838201355b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600387901b1c1916600186901b178355612bf2565b5f838152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08716915b82811015612cc25786850135825560209485019460019092019101612ca2565b5086821015612cfd577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f60208284031215612d1f575f80fd5b81516122568161260456fea2646970667358221220989eaa7e4bcd93bb65f2efef03acb1538728171421a635f02e3693d52e04ee2064736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a214a4fc09c42202c404e2976c50373fe5f5b7890000000000000000000000004300000000000000000000000000000000000002000000000000000000000000f237c20584daca970498917470864f4d027de4ca0000000000000000000000002536fe9ab3f511540f2f9e2ec2a805005c3dd800000000000000000000000000454c0c1cf7be9341d82ce0f16979b8689ed4aad0
-----Decoded View---------------
Arg [0] : owner_ (address): 0xA214a4fc09C42202C404E2976c50373fE5F5B789
Arg [1] : blast_ (address): 0x4300000000000000000000000000000000000002
Arg [2] : gasCollector_ (address): 0xf237c20584DaCA970498917470864f4d027de4ca
Arg [3] : blastPoints_ (address): 0x2536FE9ab3F511540F2f9e2eC2A805005C3Dd800
Arg [4] : pointsOperator_ (address): 0x454c0C1CF7be9341d82ce0F16979B8689ED4AAD0
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 000000000000000000000000a214a4fc09c42202c404e2976c50373fe5f5b789
Arg [1] : 0000000000000000000000004300000000000000000000000000000000000002
Arg [2] : 000000000000000000000000f237c20584daca970498917470864f4d027de4ca
Arg [3] : 0000000000000000000000002536fe9ab3f511540f2f9e2ec2a805005c3dd800
Arg [4] : 000000000000000000000000454c0c1cf7be9341d82ce0f16979b8689ed4aad0
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.