Overview
ETH Balance
0 ETH
ETH Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
ZkBobDirectDepositQueue
Compiler Version
v0.8.15+commit.e14f2714
Optimization Enabled:
Yes with 200 runs
Other Settings:
london EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "../libraries/ZkAddress.sol"; import "../interfaces/IOperatorManager.sol"; import "../interfaces/IZkBobDirectDeposits.sol"; import "../interfaces/IZkBobDirectDepositQueue.sol"; import "../interfaces/IZkBobPool.sol"; import "../utils/Ownable.sol"; import "../proxy/EIP1967Admin.sol"; /** * @title ZkBobDirectDepositQueue * Queue for zkBob direct deposits. */ contract ZkBobDirectDepositQueue is IZkBobDirectDeposits, IZkBobDirectDepositQueue, EIP1967Admin, Ownable { using SafeERC20 for IERC20; uint256 internal constant R = 21888242871839275222246405745257275088548364400416034343698204186575808495617; uint256 internal constant MAX_NUMBER_OF_DIRECT_DEPOSITS = 16; bytes4 internal constant MESSAGE_PREFIX_DIRECT_DEPOSIT_V1 = 0x00000001; uint256 internal immutable TOKEN_DENOMINATOR; uint256 internal constant TOKEN_NUMERATOR = 1000; address public immutable token; uint256 public immutable pool_id; address public immutable pool; IOperatorManager public operatorManager; mapping(uint256 => IZkBobDirectDeposits.DirectDeposit) internal directDeposits; uint32 public directDepositNonce; uint64 public directDepositFee; uint40 public directDepositTimeout; event UpdateOperatorManager(address manager); event UpdateDirectDepositFee(uint64 fee); event UpdateDirectDepositTimeout(uint40 timeout); event SubmitDirectDeposit( address indexed sender, uint256 indexed nonce, address fallbackUser, ZkAddress.ZkAddress zkAddress, uint64 deposit ); event RefundDirectDeposit(uint256 indexed nonce, address receiver, uint256 amount); event CompleteDirectDepositBatch(uint256[] indices); constructor(address _pool, address _token, uint256 _denominator) { require(Address.isContract(_token), "ZkBobDirectDepositQueue: not a contract"); require(TOKEN_NUMERATOR == 1 || _denominator == 1, "ZkBobDirectDepositQueue: incorrect denominator"); pool = _pool; token = _token; TOKEN_DENOMINATOR = _denominator; pool_id = uint24(IZkBobPool(_pool).pool_id()); } /** * @dev Updates used operator manager contract. * Operator manager in this contract is only responsible for fast-track processing of refunds. * Usage of fully permissionless operator managers is not recommended, due to existence of front-running DoS attacks. * Callable only by the contract owner / proxy admin. * @param _operatorManager new operator manager implementation. */ function setOperatorManager(IOperatorManager _operatorManager) external onlyOwner { require(address(_operatorManager) != address(0), "ZkBobDirectDepositQueue: manager is zero address"); operatorManager = _operatorManager; emit UpdateOperatorManager(address(_operatorManager)); } /** * @dev Updates direct deposit fee. * Callable only by the contract owner / proxy admin. * @param _fee new absolute fee value for making a direct deposit, in zkBOB units. */ function setDirectDepositFee(uint64 _fee) external onlyOwner { directDepositFee = _fee; emit UpdateDirectDepositFee(_fee); } /** * @dev Updates direct deposit timeout. * Callable only by the contract owner / proxy admin. * @param _timeout new timeout value for refunding non-fulfilled/rejected direct deposits. */ function setDirectDepositTimeout(uint40 _timeout) external onlyOwner { require(_timeout <= 7 days, "ZkBobDirectDepositQueue: timeout too large"); directDepositTimeout = _timeout; emit UpdateDirectDepositTimeout(_timeout); } /// @inheritdoc IZkBobDirectDeposits function getDirectDeposit(uint256 _index) external view returns (IZkBobDirectDeposits.DirectDeposit memory) { return directDeposits[_index]; } /// @inheritdoc IZkBobDirectDepositQueue function collect( uint256[] calldata _indices, uint256 _out_commit ) external returns (uint256 total, uint256 totalFee, uint256 hashsum, bytes memory message) { require(msg.sender == pool, "ZkBobDirectDepositQueue: invalid caller"); uint256 count = _indices.length; require(count > 0, "ZkBobDirectDepositQueue: empty deposit list"); require(count <= MAX_NUMBER_OF_DIRECT_DEPOSITS, "ZkBobDirectDepositQueue: too many deposits"); bytes memory input = new bytes(32 + (10 + 32 + 8) * MAX_NUMBER_OF_DIRECT_DEPOSITS); message = new bytes(4 + count * (8 + 10 + 32 + 8)); assembly { mstore(add(input, 32), _out_commit) mstore(add(message, 32), or(shl(248, count), MESSAGE_PREFIX_DIRECT_DEPOSIT_V1)) } total = 0; totalFee = 0; for (uint256 i = 0; i < count; ++i) { uint256 index = _indices[i]; DirectDeposit storage dd = directDeposits[index]; (bytes32 pk, bytes10 diversifier, uint64 deposit, uint64 fee, DirectDepositStatus status) = (dd.pk, dd.diversifier, dd.deposit, dd.fee, dd.status); require(status == DirectDepositStatus.Pending, "ZkBobDirectDepositQueue: direct deposit not pending"); assembly { // bytes10(dd.diversifier) ++ bytes32(dd.pk) ++ bytes8(dd.deposit) let offset := mul(i, 50) mstore(add(input, add(64, offset)), diversifier) mstore(add(input, add(82, offset)), deposit) mstore(add(input, add(74, offset)), pk) } assembly { // bytes8(dd.index) ++ bytes10(dd.diversifier) ++ bytes32(dd.pk) ++ bytes8(dd.deposit) let offset := mul(i, 58) mstore(add(message, add(36, offset)), shl(192, index)) mstore(add(message, add(44, offset)), diversifier) mstore(add(message, add(62, offset)), deposit) mstore(add(message, add(54, offset)), pk) } dd.status = DirectDepositStatus.Completed; total += deposit; totalFee += fee; } hashsum = uint256(keccak256(input)) % R; IERC20(token).safeTransfer(msg.sender, (total + totalFee) * TOKEN_DENOMINATOR / TOKEN_NUMERATOR); emit CompleteDirectDepositBatch(_indices); } /// @inheritdoc IZkBobDirectDeposits function directDeposit( address _fallbackUser, uint256 _amount, string calldata _zkAddress ) external returns (uint256) { return directDeposit(_fallbackUser, _amount, bytes(_zkAddress)); } /// @inheritdoc IZkBobDirectDeposits function directDeposit( address _fallbackUser, uint256 _amount, bytes memory _rawZkAddress ) public returns (uint256) { IERC20(token).safeTransferFrom(msg.sender, address(this), _amount); return _recordDirectDeposit(msg.sender, _fallbackUser, _amount, _rawZkAddress); } /// @inheritdoc IZkBobDirectDeposits function onTokenTransfer(address _from, uint256 _value, bytes calldata _data) external returns (bool) { require(msg.sender == token, "ZkBobDirectDepositQueue: not a token caller"); (address fallbackUser, bytes memory rawZkAddress) = abi.decode(_data, (address, bytes)); _recordDirectDeposit(_from, fallbackUser, _value, rawZkAddress); return true; } /// @inheritdoc IZkBobDirectDeposits function refundDirectDeposit(uint256 _index) external { bool isOperator = operatorManager.isOperator(msg.sender); DirectDeposit storage dd = directDeposits[_index]; require(dd.status == DirectDepositStatus.Pending, "ZkBobDirectDepositQueue: direct deposit not pending"); require( isOperator || dd.timestamp + directDepositTimeout < block.timestamp, "ZkBobDirectDepositQueue: direct deposit timeout not passed" ); _refundDirectDeposit(_index, dd); } /// @inheritdoc IZkBobDirectDeposits function refundDirectDeposit(uint256[] calldata _indices) external { bool isOperator = operatorManager.isOperator(msg.sender); uint256 timeout = directDepositTimeout; for (uint256 i = 0; i < _indices.length; ++i) { DirectDeposit storage dd = directDeposits[_indices[i]]; if (dd.status == DirectDepositStatus.Pending) { require( isOperator || dd.timestamp + timeout < block.timestamp, "ZkBobDirectDepositQueue: direct deposit timeout not passed" ); _refundDirectDeposit(_indices[i], dd); } } } function _refundDirectDeposit(uint256 _index, IZkBobDirectDeposits.DirectDeposit storage _dd) internal { _dd.status = IZkBobDirectDeposits.DirectDepositStatus.Refunded; (address fallbackReceiver, uint96 amount) = (_dd.fallbackReceiver, _dd.sent); IERC20(token).safeTransfer(fallbackReceiver, amount); emit RefundDirectDeposit(_index, fallbackReceiver, amount); } function _recordDirectDeposit( address _sender, address _fallbackReceiver, uint256 _amount, bytes memory _rawZkAddress ) internal returns (uint256 nonce) { require(_fallbackReceiver != address(0), "ZkBobDirectDepositQueue: fallback user is zero"); uint64 fee = directDepositFee; // small amount of wei might get lost during division, this amount will stay in the contract indefinitely uint64 depositAmount = uint64(_amount / TOKEN_DENOMINATOR * TOKEN_NUMERATOR); require(depositAmount > fee, "ZkBobDirectDepositQueue: direct deposit amount is too low"); unchecked { depositAmount -= fee; } ZkAddress.ZkAddress memory zkAddress = ZkAddress.parseZkAddress(_rawZkAddress, uint24(pool_id)); IZkBobDirectDeposits.DirectDeposit memory dd = IZkBobDirectDeposits.DirectDeposit({ fallbackReceiver: _fallbackReceiver, sent: uint96(_amount), deposit: depositAmount, fee: fee, timestamp: uint40(block.timestamp), status: DirectDepositStatus.Pending, diversifier: zkAddress.diversifier, pk: zkAddress.pk }); nonce = directDepositNonce++; directDeposits[nonce] = dd; IZkBobPool(pool).recordDirectDeposit(_sender, depositAmount); emit SubmitDirectDeposit(_sender, nonce, _fallbackReceiver, zkAddress, depositAmount); } /** * @dev Tells if caller is the contract owner. * Gives ownership rights to the proxy admin as well. * @return true, if caller is the contract owner or proxy admin. */ function _isOwner() internal view override returns (bool) { return super._isOwner() || _admin() == _msgSender(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @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 amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/draft-IERC20Permit.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: CC0-1.0 pragma solidity 0.8.15; import "@base58-solidity/Base58.sol"; /** * @title ZkAddress * Library for parsing zkBob addresses. */ library ZkAddress { uint256 internal constant R = 21888242871839275222246405745257275088548364400416034343698204186575808495617; error InvalidZkAddress(); error InvalidZkAddressLength(); error InvalidZkAddressChecksum(); struct ZkAddress { bytes10 diversifier; bytes32 pk; } /** * @notice Parses zkBob address from the zkBob UI representation. * Note that on-chain base58 decoding is quite gas intensive (610k gas), * consider to use other gas efficient formats from the below. * @param _rawZkAddress zk address base58 string representation in the zkBob UI format. * @param _poolId id of the pool to verify checksum for. */ function parseZkAddress( string calldata _rawZkAddress, uint24 _poolId ) external pure returns (ZkAddress memory res) { bytes memory _rawZkAddressBytes = bytes(_rawZkAddress); uint256 len = _len(_rawZkAddressBytes); if (len > 63 || len < 47) { revert InvalidZkAddressLength(); } // _zkAddress == Base58.encode(abi.encodePacked(bytes10(diversifier_le), bytes32(pk_le), bytes4(checksum))) bytes memory dec = Base58.decode(_rawZkAddressBytes); if (_len(dec) != 46) { revert InvalidZkAddressLength(); } res = _parseZkAddressLE46(dec, _poolId); if (uint256(res.pk) >= R) { revert InvalidZkAddress(); } } /** * @notice Parses zkBob address from the gas-efficient hex formats. * Note difference in endianness among checksummed and non-checksummed formats. * @param _rawZkAddress zk address hex representation in one of 3 formats. * @param _poolId id of the pool to verify checksum for. */ function parseZkAddress(bytes memory _rawZkAddress, uint24 _poolId) external pure returns (ZkAddress memory res) { uint256 len = _len(_rawZkAddress); if (len == 42) { // _zkAddress == abi.encodePacked(bytes10(diversifier_be), bytes32(pk_be)) res = ZkAddress(bytes10(_load(_rawZkAddress, 32)), _load(_rawZkAddress, 42)); } else if (len == 64) { // _zkAddress == abi.encode(bytes10(diversifier_be), bytes32(pk_be)) == abi.encode(ZkAddress(zkAddress)) res = abi.decode(_rawZkAddress, (ZkAddress)); } else if (len == 46) { // _zkAddress == abi.encodePacked(bytes10(diversifier_le), bytes32(pk_le), bytes4(checksum)) res = _parseZkAddressLE46(_rawZkAddress, _poolId); } else if (len < 64 && len > 46) { // _zkAddress == Base58.encode(abi.encodePacked(bytes10(diversifier_le), bytes32(pk_le), bytes4(checksum))) bytes memory dec = Base58.decode(_rawZkAddress); if (_len(dec) != 46) { revert InvalidZkAddressLength(); } res = _parseZkAddressLE46(dec, _poolId); } else { revert InvalidZkAddressLength(); } if (uint256(res.pk) >= R) { revert InvalidZkAddress(); } } function _parseZkAddressLE46(bytes memory _rawZkAddress, uint24 _poolId) internal pure returns (ZkAddress memory) { _verifyChecksum(_poolId, _rawZkAddress); bytes32 diversifier = _toLE(_load(_rawZkAddress, 32)) << 176; bytes32 pk = _toLE(_load(_rawZkAddress, 42)); return ZkAddress(bytes10(diversifier), pk); } function _verifyChecksum(uint24 _poolId, bytes memory _rawZkAddress) internal pure { bytes4 checksum = bytes4(_load(_rawZkAddress, 74)); bytes32 zkAddressHash; assembly { zkAddressHash := keccak256(add(_rawZkAddress, 32), 42) } bytes4 zkAddressChecksum1 = bytes4(zkAddressHash); bytes4 zkAddressChecksum2 = bytes4(keccak256(abi.encodePacked(_poolId, zkAddressHash))); if (checksum != zkAddressChecksum1 && checksum != zkAddressChecksum2) { revert InvalidZkAddressChecksum(); } } function _len(bytes memory _b) internal pure returns (uint256 len) { assembly { len := mload(_b) } } function _load(bytes memory _b, uint256 _offset) internal pure returns (bytes32 word) { assembly { word := mload(add(_b, _offset)) } } function _toLE(bytes32 _value) internal pure returns (bytes32 res) { assembly { res := byte(0, _value) res := add(res, shl(8, byte(1, _value))) res := add(res, shl(16, byte(2, _value))) res := add(res, shl(24, byte(3, _value))) res := add(res, shl(32, byte(4, _value))) res := add(res, shl(40, byte(5, _value))) res := add(res, shl(48, byte(6, _value))) res := add(res, shl(56, byte(7, _value))) res := add(res, shl(64, byte(8, _value))) res := add(res, shl(72, byte(9, _value))) res := add(res, shl(80, byte(10, _value))) res := add(res, shl(88, byte(11, _value))) res := add(res, shl(96, byte(12, _value))) res := add(res, shl(104, byte(13, _value))) res := add(res, shl(112, byte(14, _value))) res := add(res, shl(120, byte(15, _value))) res := add(res, shl(128, byte(16, _value))) res := add(res, shl(136, byte(17, _value))) res := add(res, shl(144, byte(18, _value))) res := add(res, shl(152, byte(19, _value))) res := add(res, shl(160, byte(20, _value))) res := add(res, shl(168, byte(21, _value))) res := add(res, shl(176, byte(22, _value))) res := add(res, shl(184, byte(23, _value))) res := add(res, shl(192, byte(24, _value))) res := add(res, shl(200, byte(25, _value))) res := add(res, shl(208, byte(26, _value))) res := add(res, shl(216, byte(27, _value))) res := add(res, shl(224, byte(28, _value))) res := add(res, shl(232, byte(29, _value))) res := add(res, shl(240, byte(30, _value))) res := add(res, shl(248, byte(31, _value))) } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.15; interface IOperatorManager { function isOperator(address _addr) external view returns (bool); function isOperatorFeeReceiver(address _operator, address _addr) external view returns (bool); function operatorURI() external view returns (string memory); }
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; interface IZkBobDirectDeposits { enum DirectDepositStatus { Missing, // requested deposit does not exist Pending, // requested deposit was submitted and is pending in the queue Completed, // requested deposit was successfully processed Refunded // requested deposit was refunded to the fallback receiver } struct DirectDeposit { address fallbackReceiver; // refund receiver for deposits that cannot be processed uint96 sent; // sent amount in BOB tokens (18 decimals) uint64 deposit; // deposit amount, after subtracting all fees (9 decimals) uint64 fee; // deposit fee (9 decimals) uint40 timestamp; // deposit submission timestamp DirectDepositStatus status; // deposit status bytes10 diversifier; // receiver zk address, part 1/2 bytes32 pk; // receiver zk address, part 2/2 } /** * @notice Retrieves the direct deposits from the queue by its id. * @param depositId id of the submitted deposit. * @return deposit recorded deposit struct */ function getDirectDeposit(uint256 depositId) external view returns (DirectDeposit memory deposit); /** * @notice Performs a direct deposit to the specified zk address. * In case the deposit cannot be processed, it can be refunded later to the fallbackReceiver address. * @param fallbackReceiver receiver of deposit refund. * @param amount direct deposit amount. * @param zkAddress receiver zk address. * @return depositId id of the submitted deposit to query status for. */ function directDeposit( address fallbackReceiver, uint256 amount, bytes memory zkAddress ) external returns (uint256 depositId); /** * @notice Performs a direct deposit to the specified zk address. * In case the deposit cannot be processed, it can be refunded later to the fallbackReceiver address. * @param fallbackReceiver receiver of deposit refund. * @param amount direct deposit amount. * @param zkAddress receiver zk address. * @return depositId id of the submitted deposit to query status for. */ function directDeposit( address fallbackReceiver, uint256 amount, string memory zkAddress ) external returns (uint256 depositId); /** * @notice ERC677 callback for performing a direct deposit. * Do not call this function directly, it's only intended to be called by the token contract. * @param from original tokens sender. * @param amount direct deposit amount. * @param data encoded address pair - abi.encode(address(fallbackReceiver), bytes(zkAddress)) * @return ok true, if deposit of submitted successfully. */ function onTokenTransfer(address from, uint256 amount, bytes memory data) external returns (bool ok); /** * @notice Tells the direct deposit fee, in zkBOB units (9 decimals). * @return fee direct deposit submission fee. */ function directDepositFee() external view returns (uint64 fee); /** * @notice Tells the timeout after which unprocessed direct deposits can be refunded. * @return timeout duration in seconds. */ function directDepositTimeout() external view returns (uint40 timeout); /** * @notice Tells the nonce of next direct deposit. * @return nonce direct deposit nonce. */ function directDepositNonce() external view returns (uint32 nonce); /** * @notice Refunds specified direct deposit. * Can be called by anyone, but only after the configured timeout has passed. * Function will revert for deposit that is not pending. * @param index deposit id to issue a refund for. */ function refundDirectDeposit(uint256 index) external; /** * @notice Refunds multiple direct deposits. * Can be called by anyone, but only after the configured timeout has passed. * Function will do nothing for non-pending deposits and will not revert. * @param indices deposit ids to issue a refund for. */ function refundDirectDeposit(uint256[] memory indices) external; }
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; interface IZkBobDirectDepositQueue { /** * @dev Collects aggregated info about submitted direct deposits and marks them as completed. * Callable only by the zkBOB pool contract. * @param _indices list of direct deposit indices to process, max of 16 indices are allowed. * @param _out_commit pre-calculated out commitment associated with the given deposits. * @return total sum of deposit amounts, not counting fees. * @return totalFee sum of deposit fees. * @return hashsum hashsum over all retrieved direct deposits. * @return message memo message to record into the tree. */ function collect( uint256[] calldata _indices, uint256 _out_commit ) external returns (uint256 total, uint256 totalFee, uint256 hashsum, bytes memory message); }
// SPDX-License-Identifier: CC0-1.0 pragma solidity ^0.8.0; interface IZkBobPool { function pool_id() external view returns (uint256); function recordDirectDeposit(address _sender, uint256 _amount) external; }
// SPDX-License-Identifier: CC0-1.0 pragma solidity 0.8.15; import "@openzeppelin/contracts/access/Ownable.sol" as OZOwnable; /** * @title Ownable */ contract Ownable is OZOwnable.Ownable { /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view override { require(_isOwner(), "Ownable: caller is not the owner"); } /** * @dev Tells if caller is the contract owner. * @return true, if caller is the contract owner. */ function _isOwner() internal view virtual returns (bool) { return owner() == _msgSender(); } }
// SPDX-License-Identifier: CC0-1.0 pragma solidity 0.8.15; /** * @title EIP1967Admin * @dev Upgradeable proxy pattern implementation according to minimalistic EIP1967. */ contract EIP1967Admin { // EIP 1967 // bytes32(uint256(keccak256('eip1967.proxy.admin')) - 1) uint256 internal constant EIP1967_ADMIN_STORAGE = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; modifier onlyAdmin() { require(msg.sender == _admin(), "EIP1967Admin: not an admin"); _; } function _admin() internal view returns (address res) { assembly { res := sload(EIP1967_ADMIN_STORAGE) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) pragma solidity ^0.8.0; /** * @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. */ 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]. */ 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 pragma solidity ^0.8.7; /** * @title Base58 * @author [email protected] * @notice This algorithm was migrated from github.com/mr-tron/base58 to solidity. * Note that it is not yet optimized for gas, so it is recommended to use it only in the view/pure function. */ library Base58 { bytes constant ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; /** * @notice encode is used to encode the given bytes in base58 standard. * @param data_ raw data, passed in as bytes. * @return base58 encoded data_, returned as bytes. */ function encode(bytes memory data_) public pure returns (bytes memory) { unchecked { uint256 size = data_.length; uint256 zeroCount; while (zeroCount < size && data_[zeroCount] == 0) { zeroCount++; } size = zeroCount + ((size - zeroCount) * 8351) / 6115 + 1; bytes memory slot = new bytes(size); uint32 carry; int256 m; int256 high = int256(size) - 1; for (uint256 i = 0; i < data_.length; i++) { m = int256(size - 1); for (carry = uint8(data_[i]); m > high || carry != 0; m--) { carry = carry + 256 * uint8(slot[uint256(m)]); slot[uint256(m)] = bytes1(uint8(carry % 58)); carry /= 58; } high = m; } uint256 n; for (n = zeroCount; n < size && slot[n] == 0; n++) {} size = slot.length - (n - zeroCount); bytes memory out = new bytes(size); for (uint256 i = 0; i < size; i++) { uint256 j = i + n - zeroCount; out[i] = ALPHABET[uint8(slot[j])]; } return out; } } /** * @notice decode is used to decode the given string in base58 standard. * @param data_ data encoded with base58, passed in as bytes. * @return raw data, returned as bytes. */ function decode(bytes memory data_) public pure returns (bytes memory) { unchecked { uint256 zero = 49; uint256 b58sz = data_.length; uint256 zcount = 0; for (uint256 i = 0; i < b58sz && uint8(data_[i]) == zero; i++) { zcount++; } uint256 t; uint256 c; bool f; bytes memory binu = new bytes(2 * (((b58sz * 8351) / 6115) + 1)); uint32[] memory outi = new uint32[]((b58sz + 3) / 4); for (uint256 i = 0; i < data_.length; i++) { bytes1 r = data_[i]; (c, f) = indexOf(ALPHABET, r); require(f, "invalid base58 digit"); for (int256 k = int256(outi.length) - 1; k >= 0; k--) { t = uint64(outi[uint256(k)]) * 58 + c; c = t >> 32; outi[uint256(k)] = uint32(t & 0xffffffff); } } uint64 mask = uint64(b58sz % 4) * 8; if (mask == 0) { mask = 32; } mask -= 8; uint256 outLen = 0; for (uint256 j = 0; j < outi.length; j++) { while (mask < 32) { binu[outLen] = bytes1(uint8(outi[j] >> mask)); outLen++; if (mask < 8) { break; } mask -= 8; } mask = 24; } for (uint256 msb = zcount; msb < binu.length; msb++) { if (binu[msb] > 0) { return slice(binu, msb - zcount, outLen); } } return slice(binu, 0, outLen); } } /** * @notice encodeToString is used to encode the given byte in base58 standard. * @param data_ raw data, passed in as bytes. * @return base58 encoded data_, returned as a string. */ function encodeToString(bytes memory data_) public pure returns (string memory) { return string(encode(data_)); } /** * @notice encodeFromString is used to encode the given string in base58 standard. * @param data_ raw data, passed in as a string. * @return base58 encoded data_, returned as bytes. */ function encodeFromString(string memory data_) public pure returns (bytes memory) { return encode(bytes(data_)); } /** * @notice decode is used to decode the given string in base58 standard. * @param data_ data encoded with base58, passed in as string. * @return raw data, returned as bytes. */ function decodeFromString(string memory data_) public pure returns (bytes memory) { return decode(bytes(data_)); } /** * @notice slice is used to slice the given byte, returns the bytes in the range of [start_, end_) * @param data_ raw data, passed in as bytes. * @param start_ start index. * @param end_ end index. * @return slice data */ function slice( bytes memory data_, uint256 start_, uint256 end_ ) public pure returns (bytes memory) { unchecked { bytes memory ret = new bytes(end_ - start_); for (uint256 i = 0; i < end_ - start_; i++) { ret[i] = data_[i + start_]; } return ret; } } /** * @notice indexOf is used to find where char_ appears in data_. * @param data_ raw data, passed in as bytes. * @param char_ target byte. * @return index, and whether the search was successful. */ function indexOf(bytes memory data_, bytes1 char_) public pure returns (uint256, bool) { unchecked { for (uint256 i = 0; i < data_.length; i++) { if (data_[i] == char_) { return (i, true); } } return (0, false); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
{ "remappings": [ "@openzeppelin/contracts/=lib/@openzeppelin/contracts/contracts/", "@gnosis/auction/=lib/@gnosis/auction/contracts/", "@base58-solidity/=lib/base58-solidity/contracts/", "forge-std/=lib/forge-std/src/", "@uniswap/=lib/@uniswap/", "base58-solidity/=lib/base58-solidity/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs" }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "london", "libraries": { "lib/base58-solidity/contracts/Base58.sol": { "Base58": "0x5eef7f755ff1a6e9ddd33e75c84a6888f6f43ed4" }, "src/libraries/ZkAddress.sol": { "ZkAddress": "0x5524e24bd944480def40cc69120cab066121e9fc" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_pool","type":"address"},{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_denominator","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"indices","type":"uint256[]"}],"name":"CompleteDirectDepositBatch","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RefundDirectDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"address","name":"fallbackUser","type":"address"},{"components":[{"internalType":"bytes10","name":"diversifier","type":"bytes10"},{"internalType":"bytes32","name":"pk","type":"bytes32"}],"indexed":false,"internalType":"struct ZkAddress.ZkAddress","name":"zkAddress","type":"tuple"},{"indexed":false,"internalType":"uint64","name":"deposit","type":"uint64"}],"name":"SubmitDirectDeposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"fee","type":"uint64"}],"name":"UpdateDirectDepositFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint40","name":"timeout","type":"uint40"}],"name":"UpdateDirectDepositTimeout","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"manager","type":"address"}],"name":"UpdateOperatorManager","type":"event"},{"inputs":[{"internalType":"uint256[]","name":"_indices","type":"uint256[]"},{"internalType":"uint256","name":"_out_commit","type":"uint256"}],"name":"collect","outputs":[{"internalType":"uint256","name":"total","type":"uint256"},{"internalType":"uint256","name":"totalFee","type":"uint256"},{"internalType":"uint256","name":"hashsum","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fallbackUser","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_rawZkAddress","type":"bytes"}],"name":"directDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fallbackUser","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"_zkAddress","type":"string"}],"name":"directDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"directDepositFee","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"directDepositNonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"directDepositTimeout","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getDirectDeposit","outputs":[{"components":[{"internalType":"address","name":"fallbackReceiver","type":"address"},{"internalType":"uint96","name":"sent","type":"uint96"},{"internalType":"uint64","name":"deposit","type":"uint64"},{"internalType":"uint64","name":"fee","type":"uint64"},{"internalType":"uint40","name":"timestamp","type":"uint40"},{"internalType":"enum IZkBobDirectDeposits.DirectDepositStatus","name":"status","type":"uint8"},{"internalType":"bytes10","name":"diversifier","type":"bytes10"},{"internalType":"bytes32","name":"pk","type":"bytes32"}],"internalType":"struct IZkBobDirectDeposits.DirectDeposit","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"onTokenTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"operatorManager","outputs":[{"internalType":"contract IOperatorManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool_id","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_indices","type":"uint256[]"}],"name":"refundDirectDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"refundDirectDeposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"_fee","type":"uint64"}],"name":"setDirectDepositFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint40","name":"_timeout","type":"uint40"}],"name":"setDirectDepositTimeout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOperatorManager","name":"_operatorManager","type":"address"}],"name":"setOperatorManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b50604051620023a7380380620023a783398101604081905262000035916200022c565b6200004033620001b0565b62000056826200020060201b62000f701760201c565b620000b85760405162461bcd60e51b815260206004820152602760248201527f5a6b426f624469726563744465706f73697451756575653a206e6f74206120636044820152661bdb9d1c9858dd60ca1b60648201526084015b60405180910390fd5b80600114620001215760405162461bcd60e51b815260206004820152602e60248201527f5a6b426f624469726563744465706f73697451756575653a20696e636f72726560448201526d31ba103232b737b6b4b730ba37b960911b6064820152608401620000af565b6001600160a01b0380841660e081905290831660a052608082905260408051632762b5b960e21b81529051639d8ad6e4916004808201926020929091908290030181865afa15801562000178573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200019e91906200026d565b62ffffff1660c0525062000287915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03163b151590565b80516001600160a01b03811681146200022757600080fd5b919050565b6000806000606084860312156200024257600080fd5b6200024d846200020f565b92506200025d602085016200020f565b9150604084015190509250925092565b6000602082840312156200028057600080fd5b5051919050565b60805160a05160c05160e0516120ae620002f96000396000818161015c01528181610ab401526113db015260008181610235015261116e015260008181610361015281816103920152818161062201528181610e8c01526114ec015260008181610e45015261107d01526120ae6000f3fe608060405234801561001057600080fd5b506004361061012c5760003560e01c8063a4c0ed36116100ad578063d7f59caa11610071578063d7f59caa14610300578063dc3ba6a314610313578063e24546f214610326578063f2fde38b14610349578063fc0c546a1461035c57600080fd5b8063a4c0ed3614610257578063b130603e1461027a578063b85369e6146102a8578063c278b761146102cd578063c41100fa146102ed57600080fd5b80636918822d116100f45780636918822d146101f1578063715018a61461020457806380a328921461020c5780638da5cb5b1461021f5780639d8ad6e41461023057600080fd5b806302592d371461013157806316f0115b146101575780632f84c96f1461019657806335d3cbcc146101a957806368dc1c55146101dc575b600080fd5b61014461013f3660046119a3565b610383565b6040519081526020015b60405180910390f35b61017e7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161014e565b60015461017e906001600160a01b031681565b6003546101c49064010000000090046001600160401b031681565b6040516001600160401b03909116815260200161014e565b6101ef6101ea366004611a46565b6103ce565b005b6101446101ff366004611ac8565b610549565b6101ef610595565b6101ef61021a366004611b23565b6105a9565b6000546001600160a01b031661017e565b6101447f000000000000000000000000000000000000000000000000000000000000000081565b61026a610265366004611ac8565b610615565b604051901515815260200161014e565b60035461029290600160601b900464ffffffffff1681565b60405164ffffffffff909116815260200161014e565b6003546102b89063ffffffff1681565b60405163ffffffff909116815260200161014e565b6102e06102db366004611b53565b6106d0565b60405161014e9190611ba4565b6101ef6102fb366004611c45565b6107ef565b6101ef61030e366004611b53565b6108b4565b6101ef610321366004611c62565b6109d8565b610339610334366004611c89565b610aa3565b60405161014e9493929190611d2c565b6101ef610357366004611c45565b610ef7565b61017e7f000000000000000000000000000000000000000000000000000000000000000081565b60006103ba6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333086610f7f565b6103c633858585610ff0565b949350505050565b6001546040516336b87bd760e11b81523360048201526000916001600160a01b031690636d70f7ae90602401602060405180830381865afa158015610417573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043b9190611d5b565b600354909150600160601b900464ffffffffff1660005b838110156105425760006002600087878581811061047257610472611d7d565b90506020020135815260200190815260200160002090506001600381111561049c5761049c611b6c565b6001820154600160a81b900460ff1660038111156104bc576104bc611b6c565b036105315783806104ea5750600181015442906104e8908590600160801b900464ffffffffff16611da9565b105b61050f5760405162461bcd60e51b815260040161050690611dc1565b60405180910390fd5b61053186868481811061052457610524611d7d565b90506020020135826114b2565b5061053b81611e1e565b9050610452565b5050505050565b600061058c858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061038392505050565b95945050505050565b61059d611565565b6105a760006115b9565b565b6105b1611565565b600380546bffffffffffffffff0000000019166401000000006001600160401b038416908102919091179091556040519081527f4fc5798183ecfb36b62f43c657e712d8b6e8661646d3c90bd3a5202335203180906020015b60405180910390a150565b6000336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106a35760405162461bcd60e51b815260206004820152602b60248201527f5a6b426f624469726563744465706f73697451756575653a206e6f742061207460448201526a37b5b2b71031b0b63632b960a91b6064820152608401610506565b6000806106b284860186611e37565b915091506106c287838884610ff0565b506001979650505050505050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260008281526002602090815260409182902082516101008101845281546001600160a01b0381168252600160a01b90046001600160601b03169281019290925260018101546001600160401b0380821694840194909452600160401b81049093166060830152600160801b830464ffffffffff166080830152909160a0830190600160a81b900460ff1660038111156107ac576107ac611b6c565b60038111156107bd576107bd611b6c565b81526001820154600160b01b900460b01b6001600160b01b031916602082015260029091015460409091015292915050565b6107f7611565565b6001600160a01b0381166108665760405162461bcd60e51b815260206004820152603060248201527f5a6b426f624469726563744465706f73697451756575653a206d616e6167657260448201526f206973207a65726f206164647265737360801b6064820152608401610506565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f267052ecaebdd552dc1b20904f59d83d51ae7add7514165322a7da9ef6cf543b9060200161060a565b6001546040516336b87bd760e11b81523360048201526000916001600160a01b031690636d70f7ae90602401602060405180830381865afa1580156108fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109219190611d5b565b6000838152600260205260409020909150600180820154600160a81b900460ff16600381111561095357610953611b6c565b146109705760405162461bcd60e51b815260040161050690611e86565b81806109ad5750600354600182015442916109a49164ffffffffff600160601b909204821691600160801b90910416611ed9565b64ffffffffff16105b6109c95760405162461bcd60e51b815260040161050690611dc1565b6109d383826114b2565b505050565b6109e0611565565b62093a808164ffffffffff161115610a4d5760405162461bcd60e51b815260206004820152602a60248201527f5a6b426f624469726563744465706f73697451756575653a2074696d656f757460448201526920746f6f206c6172676560b01b6064820152608401610506565b6003805464ffffffffff60601b1916600160601b64ffffffffff8416908102919091179091556040519081527f237f465c227da0b7fcd48ae7b5e7ec9d2ee347abbf6c93b008a616220d06ee399060200161060a565b600080806060336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610b315760405162461bcd60e51b815260206004820152602760248201527f5a6b426f624469726563744465706f73697451756575653a20696e76616c69646044820152661031b0b63632b960c91b6064820152608401610506565b8580610b935760405162461bcd60e51b815260206004820152602b60248201527f5a6b426f624469726563744465706f73697451756575653a20656d707479206460448201526a195c1bdcda5d081b1a5cdd60aa1b6064820152608401610506565b6010811115610bf75760405162461bcd60e51b815260206004820152602a60248201527f5a6b426f624469726563744465706f73697451756575653a20746f6f206d616e60448201526979206465706f7369747360b01b6064820152608401610506565b6000610c0560106032611f02565b610c10906020611da9565b6001600160401b03811115610c2757610c27611901565b6040519080825280601f01601f191660200182016040528015610c51576020820181803683370190505b509050610c5f82603a611f02565b610c6a906004611da9565b6001600160401b03811115610c8157610c81611901565b6040519080825280601f01601f191660200182016040528015610cab576020820181803683370190505b509250866020820152600160e01b8260f81b176020840152600095506000945060005b82811015610e075760008a8a83818110610cea57610cea611d7d565b6020908102929092013560008181526002938490526040902092830154600180850154929550909250600160b01b820460b01b916001600160401b0380821692600160401b830490911691600160a81b900460ff1690816003811115610d5257610d52611b6c565b14610d6f5760405162461bcd60e51b815260040161050690611e86565b6032880289016040810185905260528101849052604a0185905260c087901b603a89028c016024810191909152602c8101859052603e810184905260360185905260018601805460ff60a81b1916600160a91b179055610dd86001600160401b0384168f611da9565b9d50610ded6001600160401b0383168e611da9565b9c505050505050505080610e0090611e1e565b9050610cce565b5080516020820120610e3a907f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000190611f37565b9350610eb3336103e87f0000000000000000000000000000000000000000000000000000000000000000610e6e898b611da9565b610e789190611f02565b610e829190611f4b565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169190611609565b7f6158333d85f7dbce81f21c5dfee08ec3a6b81728f0f8ae2f329a8dcb0eac2b608989604051610ee4929190611f5f565b60405180910390a1505093509350935093565b610eff611565565b6001600160a01b038116610f645760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610506565b610f6d816115b9565b50565b6001600160a01b03163b151590565b6040516001600160a01b0380851660248301528316604482015260648101829052610fea9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611639565b50505050565b60006001600160a01b03841661105f5760405162461bcd60e51b815260206004820152602e60248201527f5a6b426f624469726563744465706f73697451756575653a2066616c6c62616360448201526d6b2075736572206973207a65726f60901b6064820152608401610506565b60035464010000000090046001600160401b031660006103e86110a27f000000000000000000000000000000000000000000000000000000000000000087611f4b565b6110ac9190611f02565b9050816001600160401b0316816001600160401b0316116111355760405162461bcd60e51b815260206004820152603960248201527f5a6b426f624469726563744465706f73697451756575653a206469726563742060448201527f6465706f73697420616d6f756e7420697320746f6f206c6f77000000000000006064820152608401610506565b60405163a7ac5aed60e01b81529082900390600090735524e24bd944480def40cc69120cab066121e9fc9063a7ac5aed906111969088907f000000000000000000000000000000000000000000000000000000000000000090600401611f9b565b6040805180830381865af41580156111b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d69190611fc2565b90506000604051806101000160405280896001600160a01b03168152602001886001600160601b03168152602001846001600160401b03168152602001856001600160401b031681526020014264ffffffffff1681526020016001600381111561124257611242611b6c565b815283516001600160b01b0319166020808301919091528401516040909101526003805491925063ffffffff90911690600061127d83612026565b825463ffffffff9182166101009390930a928302928202191691909117909155166000818152600260209081526040918290208451918501516001600160601b0316600160a01b026001600160a01b03909216919091178155908301516001820180546060860151608087015164ffffffffff16600160801b0264ffffffffff60801b196001600160401b03928316600160401b026fffffffffffffffffffffffffffffffff199094169290951691909117919091179283168117825560a086015194995085949260ff60a81b1990911665ffffffffffff60801b1990911617600160a81b83600381111561137457611374611b6c565b021790555060c082015160018201805460b09290921c600160b01b026001600160b01b0390921691909117905560e090910151600290910155604051631cbec71160e01b81526001600160a01b038a811660048301526001600160401b03851660248301527f00000000000000000000000000000000000000000000000000000000000000001690631cbec71190604401600060405180830381600087803b15801561141f57600080fd5b505af1158015611433573d6000803e3d6000fd5b5050604080516001600160a01b038c8116825286516001600160b01b031916602080840191909152870151828401526001600160401b03881660608301529151899450918d1692507fcde1b1a4bd18b6b8ddb2a80b1fce51c4eee01748267692ac6bc0770a84bc6c58919081900360800190a350505050949350505050565b60018101805460ff60a81b1916600360a81b17905580546001600160a01b0380821691600160a01b90046001600160601b031690611513907f0000000000000000000000000000000000000000000000000000000000000000168383611609565b604080516001600160a01b03841681526001600160601b038316602082015285917fb0cf2923048b0f1ffd594948402295be48a7de9d3484175e13a2cd4de8650a8c910160405180910390a250505050565b61156d61170b565b6105a75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610506565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b0383166024820152604481018290526109d390849063a9059cbb60e01b90606401610fb3565b600061168e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117509092919063ffffffff16565b8051909150156109d357808060200190518101906116ac9190611d5b565b6109d35760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610506565b600061171561175f565b8061174b57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035433905b6001600160a01b0316145b905090565b60606103c68484600085611773565b6000805433906001600160a01b0316611740565b6060824710156117d45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610506565b600080866001600160a01b031685876040516117f09190612049565b60006040518083038185875af1925050503d806000811461182d576040519150601f19603f3d011682016040523d82523d6000602084013e611832565b606091505b50915091506118438783838761184e565b979650505050505050565b606083156118bd5782516000036118b6576001600160a01b0385163b6118b65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610506565b50816103c6565b6103c683838151156118d25781518083602001fd5b8060405162461bcd60e51b81526004016105069190612065565b6001600160a01b0381168114610f6d57600080fd5b634e487b7160e01b600052604160045260246000fd5b600082601f83011261192857600080fd5b81356001600160401b038082111561194257611942611901565b604051601f8301601f19908116603f0116810190828211818310171561196a5761196a611901565b8160405283815286602085880101111561198357600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156119b857600080fd5b83356119c3816118ec565b92506020840135915060408401356001600160401b038111156119e557600080fd5b6119f186828701611917565b9150509250925092565b60008083601f840112611a0d57600080fd5b5081356001600160401b03811115611a2457600080fd5b6020830191508360208260051b8501011115611a3f57600080fd5b9250929050565b60008060208385031215611a5957600080fd5b82356001600160401b03811115611a6f57600080fd5b611a7b858286016119fb565b90969095509350505050565b60008083601f840112611a9957600080fd5b5081356001600160401b03811115611ab057600080fd5b602083019150836020828501011115611a3f57600080fd5b60008060008060608587031215611ade57600080fd5b8435611ae9816118ec565b93506020850135925060408501356001600160401b03811115611b0b57600080fd5b611b1787828801611a87565b95989497509550505050565b600060208284031215611b3557600080fd5b81356001600160401b0381168114611b4c57600080fd5b9392505050565b600060208284031215611b6557600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60048110611ba057634e487b7160e01b600052602160045260246000fd5b9052565b60006101008201905060018060a01b0383511682526001600160601b03602084015116602083015260408301516001600160401b03808216604085015280606086015116606085015250506080830151611c07608084018264ffffffffff169052565b5060a0830151611c1a60a0840182611b82565b5060c0830151611c3660c08401826001600160b01b0319169052565b5060e092830151919092015290565b600060208284031215611c5757600080fd5b8135611b4c816118ec565b600060208284031215611c7457600080fd5b813564ffffffffff81168114611b4c57600080fd5b600080600060408486031215611c9e57600080fd5b83356001600160401b03811115611cb457600080fd5b611cc0868287016119fb565b909790965060209590950135949350505050565b60005b83811015611cef578181015183820152602001611cd7565b83811115610fea5750506000910152565b60008151808452611d18816020860160208601611cd4565b601f01601f19169290920160200192915050565b848152836020820152826040820152608060608201526000611d516080830184611d00565b9695505050505050565b600060208284031215611d6d57600080fd5b81518015158114611b4c57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115611dbc57611dbc611d93565b500190565b6020808252603a908201527f5a6b426f624469726563744465706f73697451756575653a206469726563742060408201527f6465706f7369742074696d656f7574206e6f7420706173736564000000000000606082015260800190565b600060018201611e3057611e30611d93565b5060010190565b60008060408385031215611e4a57600080fd5b8235611e55816118ec565b915060208301356001600160401b03811115611e7057600080fd5b611e7c85828601611917565b9150509250929050565b60208082526033908201527f5a6b426f624469726563744465706f73697451756575653a20646972656374206040820152726465706f736974206e6f742070656e64696e6760681b606082015260800190565b600064ffffffffff808316818516808303821115611ef957611ef9611d93565b01949350505050565b6000816000190483118215151615611f1c57611f1c611d93565b500290565b634e487b7160e01b600052601260045260246000fd5b600082611f4657611f46611f21565b500690565b600082611f5a57611f5a611f21565b500490565b6020808252810182905260006001600160fb1b03831115611f7f57600080fd5b8260051b80856040850137600092016040019182525092915050565b604081526000611fae6040830185611d00565b905062ffffff831660208301529392505050565b600060408284031215611fd457600080fd5b604051604081018181106001600160401b0382111715611ff657611ff6611901565b60405282516001600160b01b03198116811461201157600080fd5b81526020928301519281019290925250919050565b600063ffffffff80831681810361203f5761203f611d93565b6001019392505050565b6000825161205b818460208701611cd4565b9190910192915050565b602081526000611b4c6020830184611d0056fea2646970667358221220e99afcaeff075d538509fb89bf27e37ae85a6dcc6545fd5636717f60441815d864736f6c634300080f00330000000000000000000000001ca8c2b9b20e18e86d5b9a72370fc6c91814c97c0000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff850000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061012c5760003560e01c8063a4c0ed36116100ad578063d7f59caa11610071578063d7f59caa14610300578063dc3ba6a314610313578063e24546f214610326578063f2fde38b14610349578063fc0c546a1461035c57600080fd5b8063a4c0ed3614610257578063b130603e1461027a578063b85369e6146102a8578063c278b761146102cd578063c41100fa146102ed57600080fd5b80636918822d116100f45780636918822d146101f1578063715018a61461020457806380a328921461020c5780638da5cb5b1461021f5780639d8ad6e41461023057600080fd5b806302592d371461013157806316f0115b146101575780632f84c96f1461019657806335d3cbcc146101a957806368dc1c55146101dc575b600080fd5b61014461013f3660046119a3565b610383565b6040519081526020015b60405180910390f35b61017e7f0000000000000000000000001ca8c2b9b20e18e86d5b9a72370fc6c91814c97c81565b6040516001600160a01b03909116815260200161014e565b60015461017e906001600160a01b031681565b6003546101c49064010000000090046001600160401b031681565b6040516001600160401b03909116815260200161014e565b6101ef6101ea366004611a46565b6103ce565b005b6101446101ff366004611ac8565b610549565b6101ef610595565b6101ef61021a366004611b23565b6105a9565b6000546001600160a01b031661017e565b6101447f000000000000000000000000000000000000000000000000000000000000000181565b61026a610265366004611ac8565b610615565b604051901515815260200161014e565b60035461029290600160601b900464ffffffffff1681565b60405164ffffffffff909116815260200161014e565b6003546102b89063ffffffff1681565b60405163ffffffff909116815260200161014e565b6102e06102db366004611b53565b6106d0565b60405161014e9190611ba4565b6101ef6102fb366004611c45565b6107ef565b6101ef61030e366004611b53565b6108b4565b6101ef610321366004611c62565b6109d8565b610339610334366004611c89565b610aa3565b60405161014e9493929190611d2c565b6101ef610357366004611c45565b610ef7565b61017e7f0000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff8581565b60006103ba6001600160a01b037f0000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff8516333086610f7f565b6103c633858585610ff0565b949350505050565b6001546040516336b87bd760e11b81523360048201526000916001600160a01b031690636d70f7ae90602401602060405180830381865afa158015610417573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043b9190611d5b565b600354909150600160601b900464ffffffffff1660005b838110156105425760006002600087878581811061047257610472611d7d565b90506020020135815260200190815260200160002090506001600381111561049c5761049c611b6c565b6001820154600160a81b900460ff1660038111156104bc576104bc611b6c565b036105315783806104ea5750600181015442906104e8908590600160801b900464ffffffffff16611da9565b105b61050f5760405162461bcd60e51b815260040161050690611dc1565b60405180910390fd5b61053186868481811061052457610524611d7d565b90506020020135826114b2565b5061053b81611e1e565b9050610452565b5050505050565b600061058c858585858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061038392505050565b95945050505050565b61059d611565565b6105a760006115b9565b565b6105b1611565565b600380546bffffffffffffffff0000000019166401000000006001600160401b038416908102919091179091556040519081527f4fc5798183ecfb36b62f43c657e712d8b6e8661646d3c90bd3a5202335203180906020015b60405180910390a150565b6000336001600160a01b037f0000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff8516146106a35760405162461bcd60e51b815260206004820152602b60248201527f5a6b426f624469726563744465706f73697451756575653a206e6f742061207460448201526a37b5b2b71031b0b63632b960a91b6064820152608401610506565b6000806106b284860186611e37565b915091506106c287838884610ff0565b506001979650505050505050565b6040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e081019190915260008281526002602090815260409182902082516101008101845281546001600160a01b0381168252600160a01b90046001600160601b03169281019290925260018101546001600160401b0380821694840194909452600160401b81049093166060830152600160801b830464ffffffffff166080830152909160a0830190600160a81b900460ff1660038111156107ac576107ac611b6c565b60038111156107bd576107bd611b6c565b81526001820154600160b01b900460b01b6001600160b01b031916602082015260029091015460409091015292915050565b6107f7611565565b6001600160a01b0381166108665760405162461bcd60e51b815260206004820152603060248201527f5a6b426f624469726563744465706f73697451756575653a206d616e6167657260448201526f206973207a65726f206164647265737360801b6064820152608401610506565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f267052ecaebdd552dc1b20904f59d83d51ae7add7514165322a7da9ef6cf543b9060200161060a565b6001546040516336b87bd760e11b81523360048201526000916001600160a01b031690636d70f7ae90602401602060405180830381865afa1580156108fd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109219190611d5b565b6000838152600260205260409020909150600180820154600160a81b900460ff16600381111561095357610953611b6c565b146109705760405162461bcd60e51b815260040161050690611e86565b81806109ad5750600354600182015442916109a49164ffffffffff600160601b909204821691600160801b90910416611ed9565b64ffffffffff16105b6109c95760405162461bcd60e51b815260040161050690611dc1565b6109d383826114b2565b505050565b6109e0611565565b62093a808164ffffffffff161115610a4d5760405162461bcd60e51b815260206004820152602a60248201527f5a6b426f624469726563744465706f73697451756575653a2074696d656f757460448201526920746f6f206c6172676560b01b6064820152608401610506565b6003805464ffffffffff60601b1916600160601b64ffffffffff8416908102919091179091556040519081527f237f465c227da0b7fcd48ae7b5e7ec9d2ee347abbf6c93b008a616220d06ee399060200161060a565b600080806060336001600160a01b037f0000000000000000000000001ca8c2b9b20e18e86d5b9a72370fc6c91814c97c1614610b315760405162461bcd60e51b815260206004820152602760248201527f5a6b426f624469726563744465706f73697451756575653a20696e76616c69646044820152661031b0b63632b960c91b6064820152608401610506565b8580610b935760405162461bcd60e51b815260206004820152602b60248201527f5a6b426f624469726563744465706f73697451756575653a20656d707479206460448201526a195c1bdcda5d081b1a5cdd60aa1b6064820152608401610506565b6010811115610bf75760405162461bcd60e51b815260206004820152602a60248201527f5a6b426f624469726563744465706f73697451756575653a20746f6f206d616e60448201526979206465706f7369747360b01b6064820152608401610506565b6000610c0560106032611f02565b610c10906020611da9565b6001600160401b03811115610c2757610c27611901565b6040519080825280601f01601f191660200182016040528015610c51576020820181803683370190505b509050610c5f82603a611f02565b610c6a906004611da9565b6001600160401b03811115610c8157610c81611901565b6040519080825280601f01601f191660200182016040528015610cab576020820181803683370190505b509250866020820152600160e01b8260f81b176020840152600095506000945060005b82811015610e075760008a8a83818110610cea57610cea611d7d565b6020908102929092013560008181526002938490526040902092830154600180850154929550909250600160b01b820460b01b916001600160401b0380821692600160401b830490911691600160a81b900460ff1690816003811115610d5257610d52611b6c565b14610d6f5760405162461bcd60e51b815260040161050690611e86565b6032880289016040810185905260528101849052604a0185905260c087901b603a89028c016024810191909152602c8101859052603e810184905260360185905260018601805460ff60a81b1916600160a91b179055610dd86001600160401b0384168f611da9565b9d50610ded6001600160401b0383168e611da9565b9c505050505050505080610e0090611e1e565b9050610cce565b5080516020820120610e3a907f30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f000000190611f37565b9350610eb3336103e87f0000000000000000000000000000000000000000000000000000000000000001610e6e898b611da9565b610e789190611f02565b610e829190611f4b565b6001600160a01b037f0000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff85169190611609565b7f6158333d85f7dbce81f21c5dfee08ec3a6b81728f0f8ae2f329a8dcb0eac2b608989604051610ee4929190611f5f565b60405180910390a1505093509350935093565b610eff611565565b6001600160a01b038116610f645760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610506565b610f6d816115b9565b50565b6001600160a01b03163b151590565b6040516001600160a01b0380851660248301528316604482015260648101829052610fea9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611639565b50505050565b60006001600160a01b03841661105f5760405162461bcd60e51b815260206004820152602e60248201527f5a6b426f624469726563744465706f73697451756575653a2066616c6c62616360448201526d6b2075736572206973207a65726f60901b6064820152608401610506565b60035464010000000090046001600160401b031660006103e86110a27f000000000000000000000000000000000000000000000000000000000000000187611f4b565b6110ac9190611f02565b9050816001600160401b0316816001600160401b0316116111355760405162461bcd60e51b815260206004820152603960248201527f5a6b426f624469726563744465706f73697451756575653a206469726563742060448201527f6465706f73697420616d6f756e7420697320746f6f206c6f77000000000000006064820152608401610506565b60405163a7ac5aed60e01b81529082900390600090735524e24bd944480def40cc69120cab066121e9fc9063a7ac5aed906111969088907f000000000000000000000000000000000000000000000000000000000000000190600401611f9b565b6040805180830381865af41580156111b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111d69190611fc2565b90506000604051806101000160405280896001600160a01b03168152602001886001600160601b03168152602001846001600160401b03168152602001856001600160401b031681526020014264ffffffffff1681526020016001600381111561124257611242611b6c565b815283516001600160b01b0319166020808301919091528401516040909101526003805491925063ffffffff90911690600061127d83612026565b825463ffffffff9182166101009390930a928302928202191691909117909155166000818152600260209081526040918290208451918501516001600160601b0316600160a01b026001600160a01b03909216919091178155908301516001820180546060860151608087015164ffffffffff16600160801b0264ffffffffff60801b196001600160401b03928316600160401b026fffffffffffffffffffffffffffffffff199094169290951691909117919091179283168117825560a086015194995085949260ff60a81b1990911665ffffffffffff60801b1990911617600160a81b83600381111561137457611374611b6c565b021790555060c082015160018201805460b09290921c600160b01b026001600160b01b0390921691909117905560e090910151600290910155604051631cbec71160e01b81526001600160a01b038a811660048301526001600160401b03851660248301527f0000000000000000000000001ca8c2b9b20e18e86d5b9a72370fc6c91814c97c1690631cbec71190604401600060405180830381600087803b15801561141f57600080fd5b505af1158015611433573d6000803e3d6000fd5b5050604080516001600160a01b038c8116825286516001600160b01b031916602080840191909152870151828401526001600160401b03881660608301529151899450918d1692507fcde1b1a4bd18b6b8ddb2a80b1fce51c4eee01748267692ac6bc0770a84bc6c58919081900360800190a350505050949350505050565b60018101805460ff60a81b1916600360a81b17905580546001600160a01b0380821691600160a01b90046001600160601b031690611513907f0000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff85168383611609565b604080516001600160a01b03841681526001600160601b038316602082015285917fb0cf2923048b0f1ffd594948402295be48a7de9d3484175e13a2cd4de8650a8c910160405180910390a250505050565b61156d61170b565b6105a75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610506565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b0383166024820152604481018290526109d390849063a9059cbb60e01b90606401610fb3565b600061168e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166117509092919063ffffffff16565b8051909150156109d357808060200190518101906116ac9190611d5b565b6109d35760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610506565b600061171561175f565b8061174b57507fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035433905b6001600160a01b0316145b905090565b60606103c68484600085611773565b6000805433906001600160a01b0316611740565b6060824710156117d45760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610506565b600080866001600160a01b031685876040516117f09190612049565b60006040518083038185875af1925050503d806000811461182d576040519150601f19603f3d011682016040523d82523d6000602084013e611832565b606091505b50915091506118438783838761184e565b979650505050505050565b606083156118bd5782516000036118b6576001600160a01b0385163b6118b65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610506565b50816103c6565b6103c683838151156118d25781518083602001fd5b8060405162461bcd60e51b81526004016105069190612065565b6001600160a01b0381168114610f6d57600080fd5b634e487b7160e01b600052604160045260246000fd5b600082601f83011261192857600080fd5b81356001600160401b038082111561194257611942611901565b604051601f8301601f19908116603f0116810190828211818310171561196a5761196a611901565b8160405283815286602085880101111561198357600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000606084860312156119b857600080fd5b83356119c3816118ec565b92506020840135915060408401356001600160401b038111156119e557600080fd5b6119f186828701611917565b9150509250925092565b60008083601f840112611a0d57600080fd5b5081356001600160401b03811115611a2457600080fd5b6020830191508360208260051b8501011115611a3f57600080fd5b9250929050565b60008060208385031215611a5957600080fd5b82356001600160401b03811115611a6f57600080fd5b611a7b858286016119fb565b90969095509350505050565b60008083601f840112611a9957600080fd5b5081356001600160401b03811115611ab057600080fd5b602083019150836020828501011115611a3f57600080fd5b60008060008060608587031215611ade57600080fd5b8435611ae9816118ec565b93506020850135925060408501356001600160401b03811115611b0b57600080fd5b611b1787828801611a87565b95989497509550505050565b600060208284031215611b3557600080fd5b81356001600160401b0381168114611b4c57600080fd5b9392505050565b600060208284031215611b6557600080fd5b5035919050565b634e487b7160e01b600052602160045260246000fd5b60048110611ba057634e487b7160e01b600052602160045260246000fd5b9052565b60006101008201905060018060a01b0383511682526001600160601b03602084015116602083015260408301516001600160401b03808216604085015280606086015116606085015250506080830151611c07608084018264ffffffffff169052565b5060a0830151611c1a60a0840182611b82565b5060c0830151611c3660c08401826001600160b01b0319169052565b5060e092830151919092015290565b600060208284031215611c5757600080fd5b8135611b4c816118ec565b600060208284031215611c7457600080fd5b813564ffffffffff81168114611b4c57600080fd5b600080600060408486031215611c9e57600080fd5b83356001600160401b03811115611cb457600080fd5b611cc0868287016119fb565b909790965060209590950135949350505050565b60005b83811015611cef578181015183820152602001611cd7565b83811115610fea5750506000910152565b60008151808452611d18816020860160208601611cd4565b601f01601f19169290920160200192915050565b848152836020820152826040820152608060608201526000611d516080830184611d00565b9695505050505050565b600060208284031215611d6d57600080fd5b81518015158114611b4c57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60008219821115611dbc57611dbc611d93565b500190565b6020808252603a908201527f5a6b426f624469726563744465706f73697451756575653a206469726563742060408201527f6465706f7369742074696d656f7574206e6f7420706173736564000000000000606082015260800190565b600060018201611e3057611e30611d93565b5060010190565b60008060408385031215611e4a57600080fd5b8235611e55816118ec565b915060208301356001600160401b03811115611e7057600080fd5b611e7c85828601611917565b9150509250929050565b60208082526033908201527f5a6b426f624469726563744465706f73697451756575653a20646972656374206040820152726465706f736974206e6f742070656e64696e6760681b606082015260800190565b600064ffffffffff808316818516808303821115611ef957611ef9611d93565b01949350505050565b6000816000190483118215151615611f1c57611f1c611d93565b500290565b634e487b7160e01b600052601260045260246000fd5b600082611f4657611f46611f21565b500690565b600082611f5a57611f5a611f21565b500490565b6020808252810182905260006001600160fb1b03831115611f7f57600080fd5b8260051b80856040850137600092016040019182525092915050565b604081526000611fae6040830185611d00565b905062ffffff831660208301529392505050565b600060408284031215611fd457600080fd5b604051604081018181106001600160401b0382111715611ff657611ff6611901565b60405282516001600160b01b03198116811461201157600080fd5b81526020928301519281019290925250919050565b600063ffffffff80831681810361203f5761203f611d93565b6001019392505050565b6000825161205b818460208701611cd4565b9190910192915050565b602081526000611b4c6020830184611d0056fea2646970667358221220e99afcaeff075d538509fb89bf27e37ae85a6dcc6545fd5636717f60441815d864736f6c634300080f0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001ca8c2b9b20e18e86d5b9a72370fc6c91814c97c0000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff850000000000000000000000000000000000000000000000000000000000000001
-----Decoded View---------------
Arg [0] : _pool (address): 0x1CA8C2B9B20E18e86d5b9a72370fC6c91814c97C
Arg [1] : _token (address): 0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85
Arg [2] : _denominator (uint256): 1
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000001ca8c2b9b20e18e86d5b9a72370fc6c91814c97c
Arg [1] : 0000000000000000000000000b2c639c533813f4aa9d7837caf62653d097ff85
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000001
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.