ETH Price: $2,064.21 (-4.29%)

Contract

0x522Eb7a9b94fC016e98e35E8562C79DDDA8Aefc0
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Publish Fee244232112026-02-10 1:52:3524 days ago1770688355IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000018140.29400641
Update Fee244232052026-02-10 1:51:2324 days ago1770688283IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000285240.32180834
Publish Fee244213492026-02-09 19:38:2324 days ago1770665903IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.00004110.63705469
Update Fee244213432026-02-09 19:37:1124 days ago1770665831IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000470930.5296779
Publish Fee244194802026-02-09 13:22:5924 days ago1770643379IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.00002750.42622364
Update Fee244194742026-02-09 13:21:4724 days ago1770643307IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000345110.38815311
Publish Fee244176122026-02-09 7:07:1125 days ago1770620831IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.00002130.33019333
Update Fee244176072026-02-09 7:06:1125 days ago1770620771IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000185270.2083996
Publish Fee244157252026-02-09 0:46:4725 days ago1770598007IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.00005370.83244106
Update Fee244157192026-02-09 0:45:3525 days ago1770597935IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000186920.21024537
Publish Fee244138622026-02-08 18:31:2325 days ago1770575483IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000287784.46033688
Update Fee244138532026-02-08 18:29:3525 days ago1770575375IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000353440.39756965
Publish Fee244119942026-02-08 12:13:5925 days ago1770552839IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000025390.39354298
Update Fee244119882026-02-08 12:12:4725 days ago1770552767IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000218330.24555982
Publish Fee244101232026-02-08 5:54:5926 days ago1770530099IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000009310.1443163
Update Fee244101172026-02-08 5:53:4726 days ago1770530027IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000217450.24456398
Publish Fee244082792026-02-07 23:38:5926 days ago1770507539IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.00001660.25741738
Update Fee244082742026-02-07 23:37:4726 days ago1770507467IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000444640.50014232
Publish Fee244064332026-02-07 17:27:4726 days ago1770485267IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000019260.2985099
Update Fee244064272026-02-07 17:26:3526 days ago1770485195IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000891071.0022195
Publish Fee244045562026-02-07 11:10:1126 days ago1770462611IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000020930.32450355
Update Fee244045502026-02-07 11:08:5926 days ago1770462539IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000371390.41777887
Publish Fee244026722026-02-07 4:51:2327 days ago1770439883IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000025840.4005896
Update Fee244026662026-02-07 4:50:1127 days ago1770439811IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000405970.45668025
Publish Fee244007862026-02-06 22:32:1127 days ago1770417131IN
0x522Eb7a9...DDA8Aefc0
0 ETH0.000031910.49468712
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
FeeManagerV3_v2

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
Yes with 100 runs

Other Settings:
cancun EvmVersion
// SPDX-License-Identifier: AGPL-3.0

pragma solidity ^0.8.24;

import {ECDSA} from "@solady/utils/ECDSA.sol";
import {Ownable} from "@solady/auth/Ownable.sol";
import {IHalo2Verifier} from "./interface/IHalo2Verifier.sol";
import {IPoolSwapFeeHelperV2} from "./interface/IPoolSwapFeeHelperV2.sol";

/**
 * @title FeeManagerV3_v2 (For Balancer V2 PoolSwapFeeHelper)
 * @notice Governs the fee management of Balancer pools with verification-based dynamic fee calculation with the PoolSwapFeeHelper
 * @dev Key change with FeeManager.sol each deployment of a FeeManager is responsible for a given token pair
 */
contract FeeManagerV3_v2 is Ownable {
    // Immutable
    // Description of the FeeManager
    string public description;
    // Swap Fee Helper Address
    IPoolSwapFeeHelperV2 public swapFeeHelper;
    // lit network public key, important note! Burn the PKP NFT after the lit action is created to ensure that the program is immutable
    // Otherwise the public key can run a different program
    address public litPublicKey;
    // EZKL Halo2Verifier Address
    IHalo2Verifier public verifier;

    // Scaling Factors for EZKL Halo2Verifier to Balancer Vault
    uint256 public scalingFactorDiv;
    uint256 public scalingFactorMul;

    // signature expiry threshold time
    uint256 public signatureExpiryThreshold;

    // Mutable
    uint256 public dynamicFee;

    // Events
    event FeeUpdated(uint256 swapFeePercentage);
    event PoolUpdated(bytes32 indexed poolId, uint256 swapFeePercentage);

    // Errors
    error VerificationFailed();
    error InvalidPool();
    error SignatureExpired();
    error SignatureFailed();

    /**
     * @notice Constructor to initialize the FeeManager contract
     * @param _description description of the FeeManager
     * @param _swapFeeHelper The swap fee helper address
     * @param _litPublicKey lit public key. important note! Burn the PKP NFT after the lit action is created to ensure that the program is immutable
     * @param _verifier EZKL's Halo2Verifier for verifying proofs
     * @param _scalingFactorDiv scaling factor to divide by, to fit instances to FixedPoint.ONE
     * @param _scalingFactorMul scaling factor to multiply by, to fit instances to FixedPoint.ONE
     */
    constructor(
        string memory _description,
        address _swapFeeHelper,
        address _litPublicKey,
        address _verifier,
        uint256 _scalingFactorDiv,
        uint256 _scalingFactorMul,
        uint256 _signatureExpiryThreshold
    ) {
        _initializeOwner(msg.sender);
        description = _description;
        swapFeeHelper = IPoolSwapFeeHelperV2(_swapFeeHelper);
        litPublicKey = _litPublicKey;
        verifier = IHalo2Verifier(_verifier);
        scalingFactorDiv = _scalingFactorDiv;
        scalingFactorMul = _scalingFactorMul;
        signatureExpiryThreshold = _signatureExpiryThreshold;
    }

    function updateSwapFeeHelper(address _swapFeeHelper) public onlyOwner {
        swapFeeHelper = IPoolSwapFeeHelperV2(_swapFeeHelper);
    }

    function updateLitPublicKey(address _litPublicKey) public onlyOwner {
        litPublicKey = _litPublicKey;
    }

    function updateVerifier(address _verifier) public onlyOwner {
        verifier = IHalo2Verifier(_verifier);
    }

    function updateSignatureExpiryThreshold(uint256 _signatureExpiryThreshold) public onlyOwner {
        signatureExpiryThreshold = _signatureExpiryThreshold;
    }

    function updateScalingFactors(uint256 _scalingFactorDiv, uint256 _scalingFactorMul) public onlyOwner {
        scalingFactorDiv = _scalingFactorDiv;
        scalingFactorMul = _scalingFactorMul;
    }

    /**
     * @notice Updates the dynamicFee on the FeeManager
     * @param proof ZK proof of the dynamic fee calculation
     * @param inputData data for the inputData
     * @param timestamp Timestamp of the data
     * @param dynamicFeeUnscaled Unscaled dynamic fee value, this should be the last element of the instances in the proof file
     * @param signature Signature of the dynamic fee calculation
     */
    function updateFee(
        bytes calldata proof,
        uint256[] calldata inputData,
        uint256 timestamp,
        uint256 dynamicFeeUnscaled,
        bytes memory signature
    ) external {
        // Check if Signature has expired to prevent replay attacks
        // Leave unchecked as timestamp + signatureExpiryThreshold is unlikely to overflow
        // an invalid timestamp would fail verification anyway
        unchecked {
            if (block.timestamp > (timestamp + signatureExpiryThreshold)) {
                revert SignatureExpired();
            }
        }
        // check input data sig
        address recovered = ECDSA.recover(keccak256(abi.encode(inputData, timestamp)), signature);

        // Check if the keys match
        if (recovered != litPublicKey) {
            revert SignatureFailed();
        }

        // build instances array with dynamicFeeUnscaled as the last element
        uint256 inputDataLength = inputData.length;
        uint256[] memory instances = new uint256[](inputDataLength + 1);

        assembly {
            // pointer to first element in instances
            let dest := add(instances, 0x20)
            // copy len * 32 bytes from calldata array payload to memory
            calldatacopy(dest, inputData.offset, mul(inputDataLength, 0x20))
            // write the trailing dynamicFeeUnscaled
            mstore(add(dest, mul(inputDataLength, 0x20)), dynamicFeeUnscaled)
        }

        // Verify the proof using the Halo2Verifier
        if (!verifier.verifyProof(proof, instances)) {
            revert VerificationFailed();
        }

        // Calculate scaled dynamicFee, we round to 5dp which is 0.00001e18 = 1e13 this is because solvers on Paraswap cannot process too many dp
        // note 100% is 1e18 as given in FixedPoint.ONE
        // note we add 5e12 to round
        dynamicFee = ((((dynamicFeeUnscaled * scalingFactorMul) / scalingFactorDiv) + 5e12) / 1e13) * 1e13;
        emit FeeUpdated(dynamicFee);
    }

    /**
     * @notice Publishes the dynamicFee by calling setStaticSwapFeePercentage on the swap fee helper
     * Pools need to have set the FeeManager contract as swap fee manager
     * @param poolIds array of pool ids
     */
    function publishFee(bytes32[] calldata poolIds) external {
        // Load variables here to reduce SLOADs
        uint256 poolsLength = poolIds.length;
        uint256 fee = dynamicFee;

        for (uint256 i = 0; i < poolsLength;) {
            swapFeeHelper.setSwapFeePercentage(poolIds[i], fee);
            emit PoolUpdated(poolIds[i], fee);
            unchecked {
                // Unlikely for poolsLength to overflow, so we leave unchecked to save gas
                ++i;
            }
        }
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Gas optimized ECDSA wrapper.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/ECDSA.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ECDSA.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/cryptography/ECDSA.sol)
///
/// @dev Note:
/// - The recovery functions use the ecrecover precompile (0x1).
/// - As of Solady version 0.0.68, the `recover` variants will revert upon recovery failure.
///   This is for more safety by default.
///   Use the `tryRecover` variants if you need to get the zero address back
///   upon recovery failure instead.
/// - As of Solady version 0.0.134, all `bytes signature` variants accept both
///   regular 65-byte `(r, s, v)` and EIP-2098 `(r, vs)` short form signatures.
///   See: https://eips.ethereum.org/EIPS/eip-2098
///   This is for calldata efficiency on smart accounts prevalent on L2s.
///
/// WARNING! Do NOT directly use signatures as unique identifiers:
/// - The recovery operations do NOT check if a signature is non-malleable.
/// - Use a nonce in the digest to prevent replay attacks on the same contract.
/// - Use EIP-712 for the digest to prevent replay attacks across different chains and contracts.
///   EIP-712 also enables readable signing of typed data for better user safety.
/// - If you need a unique hash from a signature, please use the `canonicalHash` functions.
library ECDSA {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The order of the secp256k1 elliptic curve.
    uint256 internal constant N = 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141;

    /// @dev `N/2 + 1`. Used for checking the malleability of the signature.
    uint256 private constant _HALF_N_PLUS_1 =
        0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                        CUSTOM ERRORS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The signature is invalid.
    error InvalidSignature();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                    RECOVERY OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`.
    function recover(bytes32 hash, bytes memory signature) internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            for { let m := mload(0x40) } 1 {
                mstore(0x00, 0x8baa579f) // `InvalidSignature()`.
                revert(0x1c, 0x04)
            } {
                switch mload(signature)
                case 64 {
                    let vs := mload(add(signature, 0x40))
                    mstore(0x20, add(shr(255, vs), 27)) // `v`.
                    mstore(0x60, shr(1, shl(1, vs))) // `s`.
                }
                case 65 {
                    mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`.
                    mstore(0x60, mload(add(signature, 0x40))) // `s`.
                }
                default { continue }
                mstore(0x00, hash)
                mstore(0x40, mload(add(signature, 0x20))) // `r`.
                result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20))
                mstore(0x60, 0) // Restore the zero slot.
                mstore(0x40, m) // Restore the free memory pointer.
                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                if returndatasize() { break }
            }
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`.
    function recoverCalldata(bytes32 hash, bytes calldata signature)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            for { let m := mload(0x40) } 1 {
                mstore(0x00, 0x8baa579f) // `InvalidSignature()`.
                revert(0x1c, 0x04)
            } {
                switch signature.length
                case 64 {
                    let vs := calldataload(add(signature.offset, 0x20))
                    mstore(0x20, add(shr(255, vs), 27)) // `v`.
                    mstore(0x40, calldataload(signature.offset)) // `r`.
                    mstore(0x60, shr(1, shl(1, vs))) // `s`.
                }
                case 65 {
                    mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`.
                    calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`.
                }
                default { continue }
                mstore(0x00, hash)
                result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20))
                mstore(0x60, 0) // Restore the zero slot.
                mstore(0x40, m) // Restore the free memory pointer.
                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                if returndatasize() { break }
            }
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the EIP-2098 short form signature defined by `r` and `vs`.
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x00, hash)
            mstore(0x20, add(shr(255, vs), 27)) // `v`.
            mstore(0x40, r)
            mstore(0x60, shr(1, shl(1, vs))) // `s`.
            result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20))
            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
            if iszero(returndatasize()) {
                mstore(0x00, 0x8baa579f) // `InvalidSignature()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the signature defined by `v`, `r`, `s`.
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x00, hash)
            mstore(0x20, and(v, 0xff))
            mstore(0x40, r)
            mstore(0x60, s)
            result := mload(staticcall(gas(), 1, 0x00, 0x80, 0x01, 0x20))
            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
            if iszero(returndatasize()) {
                mstore(0x00, 0x8baa579f) // `InvalidSignature()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   TRY-RECOVER OPERATIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // WARNING!
    // These functions will NOT revert upon recovery failure.
    // Instead, they will return the zero address upon recovery failure.
    // It is critical that the returned address is NEVER compared against
    // a zero address (e.g. an uninitialized address variable).

    /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`.
    function tryRecover(bytes32 hash, bytes memory signature)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            for { let m := mload(0x40) } 1 {} {
                switch mload(signature)
                case 64 {
                    let vs := mload(add(signature, 0x40))
                    mstore(0x20, add(shr(255, vs), 27)) // `v`.
                    mstore(0x60, shr(1, shl(1, vs))) // `s`.
                }
                case 65 {
                    mstore(0x20, byte(0, mload(add(signature, 0x60)))) // `v`.
                    mstore(0x60, mload(add(signature, 0x40))) // `s`.
                }
                default { break }
                mstore(0x00, hash)
                mstore(0x40, mload(add(signature, 0x20))) // `r`.
                pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20))
                mstore(0x60, 0) // Restore the zero slot.
                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                result := mload(xor(0x60, returndatasize()))
                mstore(0x40, m) // Restore the free memory pointer.
                break
            }
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`, and the `signature`.
    function tryRecoverCalldata(bytes32 hash, bytes calldata signature)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            for { let m := mload(0x40) } 1 {} {
                switch signature.length
                case 64 {
                    let vs := calldataload(add(signature.offset, 0x20))
                    mstore(0x20, add(shr(255, vs), 27)) // `v`.
                    mstore(0x40, calldataload(signature.offset)) // `r`.
                    mstore(0x60, shr(1, shl(1, vs))) // `s`.
                }
                case 65 {
                    mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40)))) // `v`.
                    calldatacopy(0x40, signature.offset, 0x40) // Copy `r` and `s`.
                }
                default { break }
                mstore(0x00, hash)
                pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20))
                mstore(0x60, 0) // Restore the zero slot.
                // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
                result := mload(xor(0x60, returndatasize()))
                mstore(0x40, m) // Restore the free memory pointer.
                break
            }
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the EIP-2098 short form signature defined by `r` and `vs`.
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x00, hash)
            mstore(0x20, add(shr(255, vs), 27)) // `v`.
            mstore(0x40, r)
            mstore(0x60, shr(1, shl(1, vs))) // `s`.
            pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20))
            mstore(0x60, 0) // Restore the zero slot.
            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
            result := mload(xor(0x60, returndatasize()))
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Recovers the signer's address from a message digest `hash`,
    /// and the signature defined by `v`, `r`, `s`.
    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
        internal
        view
        returns (address result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x00, hash)
            mstore(0x20, and(v, 0xff))
            mstore(0x40, r)
            mstore(0x60, s)
            pop(staticcall(gas(), 1, 0x00, 0x80, 0x40, 0x20))
            mstore(0x60, 0) // Restore the zero slot.
            // `returndatasize()` will be `0x20` upon success, and `0x00` otherwise.
            result := mload(xor(0x60, returndatasize()))
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     HASHING OPERATIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns an Ethereum Signed Message, created from a `hash`.
    /// This produces a hash corresponding to the one signed with the
    /// [`eth_sign`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign)
    /// JSON-RPC method as part of EIP-191.
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x20, hash) // Store into scratch space for keccak256.
            mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32") // 28 bytes.
            result := keccak256(0x04, 0x3c) // `32 * 2 - (32 - 28) = 60 = 0x3c`.
        }
    }

    /// @dev Returns an Ethereum Signed Message, created from `s`.
    /// This produces a hash corresponding to the one signed with the
    /// [`eth_sign`](https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_sign)
    /// JSON-RPC method as part of EIP-191.
    /// Note: Supports lengths of `s` up to 999999 bytes.
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let sLength := mload(s)
            let o := 0x20
            mstore(o, "\x19Ethereum Signed Message:\n") // 26 bytes, zero-right-padded.
            mstore(0x00, 0x00)
            // Convert the `s.length` to ASCII decimal representation: `base10(s.length)`.
            for { let temp := sLength } 1 {} {
                o := sub(o, 1)
                mstore8(o, add(48, mod(temp, 10)))
                temp := div(temp, 10)
                if iszero(temp) { break }
            }
            let n := sub(0x3a, o) // Header length: `26 + 32 - o`.
            // Throw an out-of-offset error (consumes all gas) if the header exceeds 32 bytes.
            returndatacopy(returndatasize(), returndatasize(), gt(n, 0x20))
            mstore(s, or(mload(0x00), mload(n))) // Temporarily store the header.
            result := keccak256(add(s, sub(0x20, n)), add(n, sLength))
            mstore(s, sLength) // Restore the length.
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  CANONICAL HASH FUNCTIONS                  */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // The following functions return the hash of the signature in its canonicalized format,
    // which is the 65-byte `abi.encodePacked(r, s, uint8(v))`, where `v` is either 27 or 28.
    // If `s` is greater than `N / 2` then it will be converted to `N - s`
    // and the `v` value will be flipped.
    // If the signature has an invalid length, or if `v` is invalid,
    // a uniquely corrupt hash will be returned.
    // These functions are useful for "poor-mans-VRF".

    /// @dev Returns the canonical hash of `signature`.
    function canonicalHash(bytes memory signature) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            let l := mload(signature)
            for {} 1 {} {
                mstore(0x00, mload(add(signature, 0x20))) // `r`.
                let s := mload(add(signature, 0x40))
                let v := mload(add(signature, 0x41))
                if eq(l, 64) {
                    v := add(shr(255, s), 27)
                    s := shr(1, shl(1, s))
                }
                if iszero(lt(s, _HALF_N_PLUS_1)) {
                    v := xor(v, 7)
                    s := sub(N, s)
                }
                mstore(0x21, v)
                mstore(0x20, s)
                result := keccak256(0x00, 0x41)
                mstore(0x21, 0) // Restore the overwritten part of the free memory pointer.
                break
            }

            // If the length is neither 64 nor 65, return a uniquely corrupted hash.
            if iszero(lt(sub(l, 64), 2)) {
                // `bytes4(keccak256("InvalidSignatureLength"))`.
                result := xor(keccak256(add(signature, 0x20), l), 0xd62f1ab2)
            }
        }
    }

    /// @dev Returns the canonical hash of `signature`.
    function canonicalHashCalldata(bytes calldata signature)
        internal
        pure
        returns (bytes32 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            for {} 1 {} {
                mstore(0x00, calldataload(signature.offset)) // `r`.
                let s := calldataload(add(signature.offset, 0x20))
                let v := calldataload(add(signature.offset, 0x21))
                if eq(signature.length, 64) {
                    v := add(shr(255, s), 27)
                    s := shr(1, shl(1, s))
                }
                if iszero(lt(s, _HALF_N_PLUS_1)) {
                    v := xor(v, 7)
                    s := sub(N, s)
                }
                mstore(0x21, v)
                mstore(0x20, s)
                result := keccak256(0x00, 0x41)
                mstore(0x21, 0) // Restore the overwritten part of the free memory pointer.
                break
            }
            // If the length is neither 64 nor 65, return a uniquely corrupted hash.
            if iszero(lt(sub(signature.length, 64), 2)) {
                calldatacopy(mload(0x40), signature.offset, signature.length)
                // `bytes4(keccak256("InvalidSignatureLength"))`.
                result := xor(keccak256(mload(0x40), signature.length), 0xd62f1ab2)
            }
        }
    }

    /// @dev Returns the canonical hash of `signature`.
    function canonicalHash(bytes32 r, bytes32 vs) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, r) // `r`.
            let v := add(shr(255, vs), 27)
            let s := shr(1, shl(1, vs))
            mstore(0x21, v)
            mstore(0x20, s)
            result := keccak256(0x00, 0x41)
            mstore(0x21, 0) // Restore the overwritten part of the free memory pointer.
        }
    }

    /// @dev Returns the canonical hash of `signature`.
    function canonicalHash(uint8 v, bytes32 r, bytes32 s) internal pure returns (bytes32 result) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, r) // `r`.
            if iszero(lt(s, _HALF_N_PLUS_1)) {
                v := xor(v, 7)
                s := sub(N, s)
            }
            mstore(0x21, v)
            mstore(0x20, s)
            result := keccak256(0x00, 0x41)
            mstore(0x21, 0) // Restore the overwritten part of the free memory pointer.
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   EMPTY CALLDATA HELPERS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns an empty calldata bytes.
    function emptySignature() internal pure returns (bytes calldata signature) {
        /// @solidity memory-safe-assembly
        assembly {
            signature.length := 0
        }
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
///
/// @dev Note:
/// This implementation does NOT auto-initialize the owner to `msg.sender`.
/// You MUST call the `_initializeOwner` in the constructor / initializer.
///
/// While the ownable portion follows
/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,
/// the nomenclature for the 2-step ownership handover may be unique to this codebase.
abstract contract Ownable {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The caller is not authorized to call the function.
    error Unauthorized();

    /// @dev The `newOwner` cannot be the zero address.
    error NewOwnerIsZeroAddress();

    /// @dev The `pendingOwner` does not have a valid handover request.
    error NoHandoverRequest();

    /// @dev Cannot double-initialize.
    error AlreadyInitialized();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.
    /// This event is intentionally kept the same as OpenZeppelin's Ownable to be
    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
    /// despite it not being as lightweight as a single argument event.
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);

    /// @dev An ownership handover to `pendingOwner` has been requested.
    event OwnershipHandoverRequested(address indexed pendingOwner);

    /// @dev The ownership handover to `pendingOwner` has been canceled.
    event OwnershipHandoverCanceled(address indexed pendingOwner);

    /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;

    /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;

    /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The owner slot is given by:
    /// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`.
    /// It is intentionally chosen to be a high value
    /// to avoid collision with lower slots.
    /// The choice of manual storage layout is to enable compatibility
    /// with both regular and upgradeable contracts.
    bytes32 internal constant _OWNER_SLOT =
        0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;

    /// The ownership handover slot of `newOwner` is given by:
    /// ```
    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
    ///     let handoverSlot := keccak256(0x00, 0x20)
    /// ```
    /// It stores the expiry timestamp of the two-step ownership handover.
    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     INTERNAL FUNCTIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Override to return true to make `_initializeOwner` prevent double-initialization.
    function _guardInitializeOwner() internal pure virtual returns (bool guard) {}

    /// @dev Initializes the owner directly without authorization guard.
    /// This function must be called upon initialization,
    /// regardless of whether the contract is upgradeable or not.
    /// This is to enable generalization to both regular and upgradeable contracts,
    /// and to save gas in case the initial owner is not the caller.
    /// For performance reasons, this function will not check if there
    /// is an existing owner.
    function _initializeOwner(address newOwner) internal virtual {
        if (_guardInitializeOwner()) {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                if sload(ownerSlot) {
                    mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.
                    revert(0x1c, 0x04)
                }
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Store the new value.
                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
            }
        } else {
            /// @solidity memory-safe-assembly
            assembly {
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Store the new value.
                sstore(_OWNER_SLOT, newOwner)
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
            }
        }
    }

    /// @dev Sets the owner directly without authorization guard.
    function _setOwner(address newOwner) internal virtual {
        if (_guardInitializeOwner()) {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
                // Store the new value.
                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
            }
        } else {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
                // Store the new value.
                sstore(ownerSlot, newOwner)
            }
        }
    }

    /// @dev Throws if the sender is not the owner.
    function _checkOwner() internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // If the caller is not the stored owner, revert.
            if iszero(eq(caller(), sload(_OWNER_SLOT))) {
                mstore(0x00, 0x82b42900) // `Unauthorized()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Returns how long a two-step ownership handover is valid for in seconds.
    /// Override to return a different value if needed.
    /// Made internal to conserve bytecode. Wrap it in a public function if needed.
    function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
        return 48 * 3600;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  PUBLIC UPDATE FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Allows the owner to transfer the ownership to `newOwner`.
    function transferOwnership(address newOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(shl(96, newOwner)) {
                mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.
                revert(0x1c, 0x04)
            }
        }
        _setOwner(newOwner);
    }

    /// @dev Allows the owner to renounce their ownership.
    function renounceOwnership() public payable virtual onlyOwner {
        _setOwner(address(0));
    }

    /// @dev Request a two-step ownership handover to the caller.
    /// The request will automatically expire in 48 hours (172800 seconds) by default.
    function requestOwnershipHandover() public payable virtual {
        unchecked {
            uint256 expires = block.timestamp + _ownershipHandoverValidFor();
            /// @solidity memory-safe-assembly
            assembly {
                // Compute and set the handover slot to `expires`.
                mstore(0x0c, _HANDOVER_SLOT_SEED)
                mstore(0x00, caller())
                sstore(keccak256(0x0c, 0x20), expires)
                // Emit the {OwnershipHandoverRequested} event.
                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
            }
        }
    }

    /// @dev Cancels the two-step ownership handover to the caller, if any.
    function cancelOwnershipHandover() public payable virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x20), 0)
            // Emit the {OwnershipHandoverCanceled} event.
            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
        }
    }

    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.
    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            let handoverSlot := keccak256(0x0c, 0x20)
            // If the handover does not exist, or has expired.
            if gt(timestamp(), sload(handoverSlot)) {
                mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
                revert(0x1c, 0x04)
            }
            // Set the handover slot to 0.
            sstore(handoverSlot, 0)
        }
        _setOwner(pendingOwner);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   PUBLIC READ FUNCTIONS                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the owner of the contract.
    function owner() public view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := sload(_OWNER_SLOT)
        }
    }

    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
    function ownershipHandoverExpiresAt(address pendingOwner)
        public
        view
        virtual
        returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the handover slot.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            // Load the handover slot.
            result := sload(keccak256(0x0c, 0x20))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         MODIFIERS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Marks a function as only callable by the owner.
    modifier onlyOwner() virtual {
        _checkOwner();
        _;
    }
}

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/**
 * @title Halo2Verifier from ezkl
 * @notice This is the Halo2Verifier from the ezkl library
 * You will need to obtain the PK (proving key) in order to generate the proof and instances
 */
interface IHalo2Verifier {
    function verifyProof(bytes calldata proof, uint256[] calldata instances) external returns (bool);
}

// SPDX-License-Identifier: GPL-3.0-or-later
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

pragma solidity >=0.7.0 <0.9.0;

/**
 * @notice Maintain a set of pools whose static swap fee percentages can be changed from here, vs. directly on the pool.
 * @dev Governance can add a set of pools to this contract, then grant swap fee setting permission to accounts on this
 * contract, which allows greater granularity than setting the permission directly on the pool contracts.
 * @dev Truncated version of the IPoolSwapFeeHelper interface for the FeeManagerV3_v2 contract
 */
interface IPoolSwapFeeHelperV2 {
    /**
     *
     *                                 Manage Pools
     *
     */

    /**
     * @notice Set the swap fee percentage on a given pool.
     * @dev This is a permissioned function. Governance must grant this contract permission to call
     * `setSwapFeePercentage` on the pool. Since action ids are factory-based, this must be done for each pool type.
     *
     * @param poolId The ID of the pool
     * @param swapFeePercentage The new swap fee percentage
     */
    function setSwapFeePercentage(bytes32 poolId, uint256 swapFeePercentage) external;
}

Settings
{
  "remappings": [
    "@openzeppelin/=lib/openzeppelin-contracts/",
    "@solady/=lib/solady/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/",
    "solady/=lib/solady/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 100
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": false
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"string","name":"_description","type":"string"},{"internalType":"address","name":"_swapFeeHelper","type":"address"},{"internalType":"address","name":"_litPublicKey","type":"address"},{"internalType":"address","name":"_verifier","type":"address"},{"internalType":"uint256","name":"_scalingFactorDiv","type":"uint256"},{"internalType":"uint256","name":"_scalingFactorMul","type":"uint256"},{"internalType":"uint256","name":"_signatureExpiryThreshold","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"InvalidPool","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"SignatureExpired","type":"error"},{"inputs":[],"name":"SignatureFailed","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"VerificationFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"swapFeePercentage","type":"uint256"}],"name":"FeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"poolId","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"swapFeePercentage","type":"uint256"}],"name":"PoolUpdated","type":"event"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dynamicFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"litPublicKey","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"poolIds","type":"bytes32[]"}],"name":"publishFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"scalingFactorDiv","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"scalingFactorMul","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signatureExpiryThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapFeeHelper","outputs":[{"internalType":"contract IPoolSwapFeeHelperV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"proof","type":"bytes"},{"internalType":"uint256[]","name":"inputData","type":"uint256[]"},{"internalType":"uint256","name":"timestamp","type":"uint256"},{"internalType":"uint256","name":"dynamicFeeUnscaled","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"updateFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_litPublicKey","type":"address"}],"name":"updateLitPublicKey","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_scalingFactorDiv","type":"uint256"},{"internalType":"uint256","name":"_scalingFactorMul","type":"uint256"}],"name":"updateScalingFactors","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_signatureExpiryThreshold","type":"uint256"}],"name":"updateSignatureExpiryThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_swapFeeHelper","type":"address"}],"name":"updateSwapFeeHelper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_verifier","type":"address"}],"name":"updateVerifier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"verifier","outputs":[{"internalType":"contract IHalo2Verifier","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

608060405234801561000f575f80fd5b5060405161112738038061112783398101604081905261002e91610100565b61003733610096565b5f6100428882610282565b50600180546001600160a01b03199081166001600160a01b0398891617909155600280548216968816969096179095556003805490951693909516929092179092556004919091556005556006555061033c565b6001600160a01b0316638b78c6d819819055805f7f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b634e487b7160e01b5f52604160045260245ffd5b80516001600160a01b03811681146100fb575f80fd5b919050565b5f805f805f805f60e0888a031215610116575f80fd5b87516001600160401b0381111561012b575f80fd5b8801601f81018a1361013b575f80fd5b80516001600160401b03811115610154576101546100d1565b604051601f8201601f19908116603f011681016001600160401b0381118282101715610182576101826100d1565b6040528181528282016020018c1015610199575f80fd5b8160208401602083015e5f602083830101528099505050506101bd602089016100e5565b95506101cb604089016100e5565b94506101d9606089016100e5565b608089015160a08a015160c0909a0151989b979a509598909795969095945092505050565b600181811c9082168061021257607f821691505b60208210810361023057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561027d57805f5260205f20601f840160051c8101602085101561025b5750805b601f840160051c820191505b8181101561027a575f8155600101610267565b50505b505050565b81516001600160401b0381111561029b5761029b6100d1565b6102af816102a984546101fe565b84610236565b6020601f8211600181146102e1575f83156102ca5750848201515b5f19600385901b1c1916600184901b17845561027a565b5f84815260208120601f198516915b8281101561031057878501518255602094850194600190920191016102f0565b508482101561032d57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b610dde806103495f395ff3fe608060405260043610610131575f3560e01c80638da5cb5b116100a8578063b39db6861161006d578063b39db686146102ea578063ef2c21d914610309578063f04e283e1461031e578063f2fde38b14610331578063fbcbc5e614610344578063fee81cf414610363575f80fd5b80638da5cb5b1461026a57806397fc007c146102825780639b19f356146102a1578063a3b1bc24146102b6578063b20d550b146102d5575f80fd5b80636250bb55116100f95780636250bb55146101c5578063715018a6146101e45780637284e416146101ec5780637e390d591461020d57806384a101541461022c5780638771b6641461024b575f80fd5b806325692962146101355780632b7ac3f31461013f5780633534d6941461017b5780633ad5a7241461019a57806354d1f13d146101bd575b5f80fd5b61013d610394565b005b34801561014a575f80fd5b5060035461015e906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610186575f80fd5b5061013d610195366004610a7c565b6103e0565b3480156101a5575f80fd5b506101af60055481565b604051908152602001610172565b61013d6105ef565b3480156101d0575f80fd5b5061013d6101df366004610b4f565b610628565b61013d610652565b3480156101f7575f80fd5b50610200610665565b6040516101729190610b7c565b348015610218575f80fd5b5061013d610227366004610bb1565b6106f0565b348015610237575f80fd5b5061013d610246366004610bc8565b6106fd565b348015610256575f80fd5b5061013d610265366004610b4f565b610710565b348015610275575f80fd5b50638b78c6d8195461015e565b34801561028d575f80fd5b5061013d61029c366004610b4f565b61073a565b3480156102ac575f80fd5b506101af60045481565b3480156102c1575f80fd5b5060025461015e906001600160a01b031681565b3480156102e0575f80fd5b506101af60075481565b3480156102f5575f80fd5b5061013d610304366004610be8565b610764565b348015610314575f80fd5b506101af60065481565b61013d61032c366004610b4f565b610852565b61013d61033f366004610b4f565b61088f565b34801561034f575f80fd5b5060015461015e906001600160a01b031681565b34801561036e575f80fd5b506101af61037d366004610b4f565b63389a75e1600c9081525f91909152602090205490565b5f6202a3006001600160401b03164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a250565b600654830142111561040557604051630819bdcd60e01b815260040160405180910390fd5b5f61043a86868660405160200161041e93929190610c26565b60405160208183030381529060405280519060200120836108b5565b6002549091506001600160a01b0380831691161461046b5760405163338a70bd60e11b815260040160405180910390fd5b845f610478826001610c76565b6001600160401b0381111561048f5761048f6109df565b6040519080825280602002602001820160405280156104b8578160200160208202803683370190505b50905060208101602083028982376020830201859052600354604051631e8e1e1360e01b81526001600160a01b0390911690631e8e1e1390610502908d908d908690600401610c8f565b6020604051808303815f875af115801561051e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105429190610d07565b61055f5760405163439cc0cd60e01b815260040160405180910390fd5b6509184e72a000600454600554876105779190610d26565b6105819190610d3d565b6105919065048c27395000610c76565b61059b9190610d3d565b6105ab906509184e72a000610d26565b60078190556040519081527f8c4d35e54a3f2ef1134138fd8ea3daee6a3c89e10d2665996babdf70261e2c769060200160405180910390a150505050505050505050565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2565b610630610941565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b61065a610941565b6106635f61095b565b565b5f805461067190610d5c565b80601f016020809104026020016040519081016040528092919081815260200182805461069d90610d5c565b80156106e85780601f106106bf576101008083540402835291602001916106e8565b820191905f5260205f20905b8154815290600101906020018083116106cb57829003601f168201915b505050505081565b6106f8610941565b600655565b610705610941565b600491909155600555565b610718610941565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b610742610941565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60075481905f5b8281101561084b576001546001600160a01b0316634d578eaf86868481811061079657610796610d94565b90506020020135846040518363ffffffff1660e01b81526004016107c4929190918252602082015260400190565b5f604051808303815f87803b1580156107db575f80fd5b505af11580156107ed573d5f803e3d5ffd5b5050505084848281811061080357610803610d94565b905060200201357f1fcb7d0fda33670fdf4237d8d7a473a941ba0d52671063a86f901de935483e328360405161083b91815260200190565b60405180910390a260010161076b565b5050505050565b61085a610941565b63389a75e1600c52805f526020600c20805442111561088057636f5e88185f526004601cfd5b5f905561088c8161095b565b50565b610897610941565b8060601b6108ac57637448fbae5f526004601cfd5b61088c8161095b565b5f6040518251604081146108d157604181146108f2575061092d565b604084015160ff81901c601b016020526001600160ff1b0316606052610905565b60608401515f1a60205260408401516060525b50835f5260208301516040526020600160805f60015afa5191505f606052806040523d61093a575b638baa579f5f526004601cfd5b5092915050565b638b78c6d819543314610663576382b429005f526004601cfd5b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a355565b5f8083601f8401126109a8575f80fd5b5081356001600160401b038111156109be575f80fd5b6020830191508360208260051b85010111156109d8575f80fd5b9250929050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112610a02575f80fd5b81356001600160401b03811115610a1b57610a1b6109df565b604051601f8201601f19908116603f011681016001600160401b0381118282101715610a4957610a496109df565b604052818152838201602001851015610a60575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f805f805f60a0888a031215610a92575f80fd5b87356001600160401b03811115610aa7575f80fd5b8801601f81018a13610ab7575f80fd5b80356001600160401b03811115610acc575f80fd5b8a6020828401011115610add575f80fd5b6020918201985096508801356001600160401b03811115610afc575f80fd5b610b088a828b01610998565b909650945050604088013592506060880135915060808801356001600160401b03811115610b34575f80fd5b610b408a828b016109f3565b91505092959891949750929550565b5f60208284031215610b5f575f80fd5b81356001600160a01b0381168114610b75575f80fd5b9392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f60208284031215610bc1575f80fd5b5035919050565b5f8060408385031215610bd9575f80fd5b50508035926020909101359150565b5f8060208385031215610bf9575f80fd5b82356001600160401b03811115610c0e575f80fd5b610c1a85828601610998565b90969095509350505050565b604080825281018390525f6001600160fb1b03841115610c44575f80fd5b8360051b808660608501376020830193909352500160600192915050565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610c8957610c89610c62565b92915050565b60408152826040820152828460608301375f606084830101525f601f19601f85011682016060810160608483030160208501528085518083526080840191506020870193505f92505b80831015610cfb5783518252602082019150602084019350600183019250610cd8565b50979650505050505050565b5f60208284031215610d17575f80fd5b81518015158114610b75575f80fd5b8082028115828204841417610c8957610c89610c62565b5f82610d5757634e487b7160e01b5f52601260045260245ffd5b500490565b600181811c90821680610d7057607f821691505b602082108103610d8e57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220909ee3765dcf0e0d456dc9089eedccca6d3ed97e082e75d1aa7940bd2c95c5e064736f6c634300081a003300000000000000000000000000000000000000000000000000000000000000e00000000000000000000000001a601e2aadb0710c587b7c6b13a014290702250800000000000000000000000030fe0fd65e89fc2bfb8a4b4a06cfcba0070ff0b7000000000000000000000000e47f07cc96b269c68e4a2a5b9b3bd0e02c6ae698000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000000000000000000000627000000000000000000000000000000000000000000000000000000000000000094141564545544836680000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405260043610610131575f3560e01c80638da5cb5b116100a8578063b39db6861161006d578063b39db686146102ea578063ef2c21d914610309578063f04e283e1461031e578063f2fde38b14610331578063fbcbc5e614610344578063fee81cf414610363575f80fd5b80638da5cb5b1461026a57806397fc007c146102825780639b19f356146102a1578063a3b1bc24146102b6578063b20d550b146102d5575f80fd5b80636250bb55116100f95780636250bb55146101c5578063715018a6146101e45780637284e416146101ec5780637e390d591461020d57806384a101541461022c5780638771b6641461024b575f80fd5b806325692962146101355780632b7ac3f31461013f5780633534d6941461017b5780633ad5a7241461019a57806354d1f13d146101bd575b5f80fd5b61013d610394565b005b34801561014a575f80fd5b5060035461015e906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610186575f80fd5b5061013d610195366004610a7c565b6103e0565b3480156101a5575f80fd5b506101af60055481565b604051908152602001610172565b61013d6105ef565b3480156101d0575f80fd5b5061013d6101df366004610b4f565b610628565b61013d610652565b3480156101f7575f80fd5b50610200610665565b6040516101729190610b7c565b348015610218575f80fd5b5061013d610227366004610bb1565b6106f0565b348015610237575f80fd5b5061013d610246366004610bc8565b6106fd565b348015610256575f80fd5b5061013d610265366004610b4f565b610710565b348015610275575f80fd5b50638b78c6d8195461015e565b34801561028d575f80fd5b5061013d61029c366004610b4f565b61073a565b3480156102ac575f80fd5b506101af60045481565b3480156102c1575f80fd5b5060025461015e906001600160a01b031681565b3480156102e0575f80fd5b506101af60075481565b3480156102f5575f80fd5b5061013d610304366004610be8565b610764565b348015610314575f80fd5b506101af60065481565b61013d61032c366004610b4f565b610852565b61013d61033f366004610b4f565b61088f565b34801561034f575f80fd5b5060015461015e906001600160a01b031681565b34801561036e575f80fd5b506101af61037d366004610b4f565b63389a75e1600c9081525f91909152602090205490565b5f6202a3006001600160401b03164201905063389a75e1600c52335f52806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d5f80a250565b600654830142111561040557604051630819bdcd60e01b815260040160405180910390fd5b5f61043a86868660405160200161041e93929190610c26565b60405160208183030381529060405280519060200120836108b5565b6002549091506001600160a01b0380831691161461046b5760405163338a70bd60e11b815260040160405180910390fd5b845f610478826001610c76565b6001600160401b0381111561048f5761048f6109df565b6040519080825280602002602001820160405280156104b8578160200160208202803683370190505b50905060208101602083028982376020830201859052600354604051631e8e1e1360e01b81526001600160a01b0390911690631e8e1e1390610502908d908d908690600401610c8f565b6020604051808303815f875af115801561051e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105429190610d07565b61055f5760405163439cc0cd60e01b815260040160405180910390fd5b6509184e72a000600454600554876105779190610d26565b6105819190610d3d565b6105919065048c27395000610c76565b61059b9190610d3d565b6105ab906509184e72a000610d26565b60078190556040519081527f8c4d35e54a3f2ef1134138fd8ea3daee6a3c89e10d2665996babdf70261e2c769060200160405180910390a150505050505050505050565b63389a75e1600c52335f525f6020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c925f80a2565b610630610941565b600180546001600160a01b0319166001600160a01b0392909216919091179055565b61065a610941565b6106635f61095b565b565b5f805461067190610d5c565b80601f016020809104026020016040519081016040528092919081815260200182805461069d90610d5c565b80156106e85780601f106106bf576101008083540402835291602001916106e8565b820191905f5260205f20905b8154815290600101906020018083116106cb57829003601f168201915b505050505081565b6106f8610941565b600655565b610705610941565b600491909155600555565b610718610941565b600280546001600160a01b0319166001600160a01b0392909216919091179055565b610742610941565b600380546001600160a01b0319166001600160a01b0392909216919091179055565b60075481905f5b8281101561084b576001546001600160a01b0316634d578eaf86868481811061079657610796610d94565b90506020020135846040518363ffffffff1660e01b81526004016107c4929190918252602082015260400190565b5f604051808303815f87803b1580156107db575f80fd5b505af11580156107ed573d5f803e3d5ffd5b5050505084848281811061080357610803610d94565b905060200201357f1fcb7d0fda33670fdf4237d8d7a473a941ba0d52671063a86f901de935483e328360405161083b91815260200190565b60405180910390a260010161076b565b5050505050565b61085a610941565b63389a75e1600c52805f526020600c20805442111561088057636f5e88185f526004601cfd5b5f905561088c8161095b565b50565b610897610941565b8060601b6108ac57637448fbae5f526004601cfd5b61088c8161095b565b5f6040518251604081146108d157604181146108f2575061092d565b604084015160ff81901c601b016020526001600160ff1b0316606052610905565b60608401515f1a60205260408401516060525b50835f5260208301516040526020600160805f60015afa5191505f606052806040523d61093a575b638baa579f5f526004601cfd5b5092915050565b638b78c6d819543314610663576382b429005f526004601cfd5b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a355565b5f8083601f8401126109a8575f80fd5b5081356001600160401b038111156109be575f80fd5b6020830191508360208260051b85010111156109d8575f80fd5b9250929050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112610a02575f80fd5b81356001600160401b03811115610a1b57610a1b6109df565b604051601f8201601f19908116603f011681016001600160401b0381118282101715610a4957610a496109df565b604052818152838201602001851015610a60575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f805f805f60a0888a031215610a92575f80fd5b87356001600160401b03811115610aa7575f80fd5b8801601f81018a13610ab7575f80fd5b80356001600160401b03811115610acc575f80fd5b8a6020828401011115610add575f80fd5b6020918201985096508801356001600160401b03811115610afc575f80fd5b610b088a828b01610998565b909650945050604088013592506060880135915060808801356001600160401b03811115610b34575f80fd5b610b408a828b016109f3565b91505092959891949750929550565b5f60208284031215610b5f575f80fd5b81356001600160a01b0381168114610b75575f80fd5b9392505050565b602081525f82518060208401528060208501604085015e5f604082850101526040601f19601f83011684010191505092915050565b5f60208284031215610bc1575f80fd5b5035919050565b5f8060408385031215610bd9575f80fd5b50508035926020909101359150565b5f8060208385031215610bf9575f80fd5b82356001600160401b03811115610c0e575f80fd5b610c1a85828601610998565b90969095509350505050565b604080825281018390525f6001600160fb1b03841115610c44575f80fd5b8360051b808660608501376020830193909352500160600192915050565b634e487b7160e01b5f52601160045260245ffd5b80820180821115610c8957610c89610c62565b92915050565b60408152826040820152828460608301375f606084830101525f601f19601f85011682016060810160608483030160208501528085518083526080840191506020870193505f92505b80831015610cfb5783518252602082019150602084019350600183019250610cd8565b50979650505050505050565b5f60208284031215610d17575f80fd5b81518015158114610b75575f80fd5b8082028115828204841417610c8957610c89610c62565b5f82610d5757634e487b7160e01b5f52601260045260245ffd5b500490565b600181811c90821680610d7057607f821691505b602082108103610d8e57634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52603260045260245ffdfea2646970667358221220909ee3765dcf0e0d456dc9089eedccca6d3ed97e082e75d1aa7940bd2c95c5e064736f6c634300081a0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000001a601e2aadb0710c587b7c6b13a014290702250800000000000000000000000030fe0fd65e89fc2bfb8a4b4a06cfcba0070ff0b7000000000000000000000000e47f07cc96b269c68e4a2a5b9b3bd0e02c6ae698000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000000000000000000000627000000000000000000000000000000000000000000000000000000000000000094141564545544836680000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _description (string): AAVEETH6h
Arg [1] : _swapFeeHelper (address): 0x1a601E2AadB0710c587b7c6B13A0142907022508
Arg [2] : _litPublicKey (address): 0x30fe0Fd65E89fc2bFB8A4b4a06cfcBa0070ff0b7
Arg [3] : _verifier (address): 0xe47F07cc96B269C68e4A2a5b9b3bd0E02c6aE698
Arg [4] : _scalingFactorDiv (uint256): 1048576
Arg [5] : _scalingFactorMul (uint256): 100000000000000
Arg [6] : _signatureExpiryThreshold (uint256): 25200

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [1] : 0000000000000000000000001a601e2aadb0710c587b7c6b13a0142907022508
Arg [2] : 00000000000000000000000030fe0fd65e89fc2bfb8a4b4a06cfcba0070ff0b7
Arg [3] : 000000000000000000000000e47f07cc96b269c68e4a2a5b9b3bd0e02c6ae698
Arg [4] : 0000000000000000000000000000000000000000000000000000000000100000
Arg [5] : 00000000000000000000000000000000000000000000000000005af3107a4000
Arg [6] : 0000000000000000000000000000000000000000000000000000000000006270
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000009
Arg [8] : 4141564545544836680000000000000000000000000000000000000000000000


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.