ETH Price: $2,790.00 (-5.71%)

Contract

0xDa14Fdd72345c4d2511357214c5B89A919768e59

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To
Create Account383987462026-01-23 5:45:052 days ago1769147105IN
0xDa14Fdd7...919768e59
0 ETH0.000000620.00225
Create Account374711192026-01-12 12:04:3813 days ago1768219478IN
0xDa14Fdd7...919768e59
0 ETH0.000000020.0001003
Create Account374209092026-01-11 22:07:4814 days ago1768169268IN
0xDa14Fdd7...919768e59
0 ETH0.000000020.00010027
Create Account373587412026-01-11 4:51:4014 days ago1768107100IN
0xDa14Fdd7...919768e59
0 ETH00.00000025
Create Account372245712026-01-09 15:35:3016 days ago1767972930IN
0xDa14Fdd7...919768e59
0 ETH0.000000020.00010027
Create Account372195792026-01-09 14:12:1816 days ago1767967938IN
0xDa14Fdd7...919768e59
0 ETH0.000000020.00010025
Create Account372171462026-01-09 13:31:4516 days ago1767965505IN
0xDa14Fdd7...919768e59
0 ETH0.000000020.0001003
Create Account371316762026-01-08 13:47:1517 days ago1767880035IN
0xDa14Fdd7...919768e59
0 ETH00.00000036
Create Account371136482026-01-08 8:46:4717 days ago1767862007IN
0xDa14Fdd7...919768e59
0 ETH0.000000020.00010025
Create Account354100812025-12-19 15:34:0037 days ago1766158440IN
0xDa14Fdd7...919768e59
0 ETH0.000000030.00010032
Create Account346307372025-12-10 15:04:5646 days ago1765379096IN
0xDa14Fdd7...919768e59
0 ETH0.000000020.00010028
Create Account345507752025-12-09 16:52:1447 days ago1765299134IN
0xDa14Fdd7...919768e59
0 ETH0.000000030.00010029
Create Account345507052025-12-09 16:51:0447 days ago1765299064IN
0xDa14Fdd7...919768e59
0 ETH0.000000040.00013346
Create Account345232512025-12-09 9:13:3047 days ago1765271610IN
0xDa14Fdd7...919768e59
0 ETH0.000000020.00010027
Create Account345204622025-12-09 8:27:0147 days ago1765268821IN
0xDa14Fdd7...919768e59
0 ETH0.000000030.00010027

Latest 15 internal transactions

Advanced mode:
Parent Transaction Hash Block From To
383987462026-01-23 5:45:052 days ago1769147105
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
374711192026-01-12 12:04:3813 days ago1768219478
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
374209092026-01-11 22:07:4814 days ago1768169268
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
373587412026-01-11 4:51:4014 days ago1768107100
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
372245712026-01-09 15:35:3016 days ago1767972930
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
372195792026-01-09 14:12:1816 days ago1767967938
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
372171462026-01-09 13:31:4516 days ago1767965505
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
371316762026-01-08 13:47:1517 days ago1767880035
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
371136482026-01-08 8:46:4717 days ago1767862007
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
354100812025-12-19 15:34:0037 days ago1766158440
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
346307372025-12-10 15:04:5646 days ago1765379096
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
345507752025-12-09 16:52:1447 days ago1765299134
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
345507052025-12-09 16:51:0447 days ago1765299064
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
345232512025-12-09 9:13:3047 days ago1765271610
0xDa14Fdd7...919768e59
 Contract Creation0 ETH
345204622025-12-09 8:27:0147 days ago1765268821
0xDa14Fdd7...919768e59
 Contract Creation0 ETH

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Factory

Compiler Version
v0.8.30+commit.73712a01

Optimization Enabled:
Yes with 200 runs

Other Settings:
prague EvmVersion
/**
 * Created by Pragma Labs
 * SPDX-License-Identifier: BUSL-1.1
 */
pragma solidity ^0.8.30;

import { CreateProxyLib } from "./libraries/CreateProxyLib.sol";
import { ERC721, ERC721TokenReceiver } from "../lib/solmate/src/tokens/ERC721.sol";
import { FactoryErrors } from "./libraries/Errors.sol";
import { FactoryGuardian } from "./guardians/FactoryGuardian.sol";
import { IAccount } from "./interfaces/IAccount.sol";
import { IFactory } from "./interfaces/IFactory.sol";
import { IRegistry } from "./interfaces/IRegistry.sol";
import { MerkleProofLib } from "../lib/solmate/src/utils/MerkleProofLib.sol";
import { Strings } from "./libraries/Strings.sol";

/**
 * @title Factory
 * @author Pragma Labs
 * @notice The Factory manages the deployment, upgrades and transfers of Arcadia Accounts.
 * @dev The Factory is an ERC721 contract that maps each id to an Arcadia Account.
 */
contract Factory is IFactory, ERC721, FactoryGuardian {
    using Strings for uint256;

    /* //////////////////////////////////////////////////////////////
                                STORAGE
    ////////////////////////////////////////////////////////////// */

    // The latest Account version, newly deployed Account use the latest version by default.
    uint88 public latestAccountVersion;
    // The baseURI of the ERC721 tokens.
    // forge-lint: disable-next-item(mixed-case-variable)
    string public baseURI;

    // The Merkle root of the Merkle tree of all the compatible Account versions.
    bytes32 public versionRoot;

    // Array of all Arcadia Account contract addresses.
    address[] public allAccounts;

    // Map accountVersion => blocked status.
    mapping(uint256 => bool) public accountVersionBlocked;
    // Map accountAddress => accountIndex.
    mapping(address => uint256) public accountIndex;
    // Map accountVersion => version information.
    mapping(uint256 => VersionInformation) public versionInformation;

    // Struct with additional information for a specific Account version.
    struct VersionInformation {
        // The contract address of the Registry.
        address registry;
        // The contract address of the Account implementation.
        address implementation;
        // Arbitrary data, can contain instructions to execute when updating Account to new implementation.
        bytes data;
    }

    /* //////////////////////////////////////////////////////////////
                                EVENTS
    ////////////////////////////////////////////////////////////// */

    event AccountUpgraded(address indexed accountAddress, uint88 indexed newVersion);
    event AccountVersionAdded(uint88 indexed version, address indexed registry, address indexed implementation);
    event AccountVersionBlocked(uint88 version);

    /* //////////////////////////////////////////////////////////////
                                CONSTRUCTOR
    ////////////////////////////////////////////////////////////// */

    /**
     * @param owner_ The address of the Owner.
     */
    constructor(address owner_) ERC721("Arcadia Account", "ARCADIA") FactoryGuardian(owner_) { }

    /*///////////////////////////////////////////////////////////////
                          ACCOUNT MANAGEMENT
    ///////////////////////////////////////////////////////////////*/

    /**
     * @notice Function to create a new Account.
     * @param userSalt A salt, provided by the user, to generate the Account address.
     * @param accountVersion The Account version.
     * @param creditor The contract address of the creditor.
     * @return account The contract address of the Proxy of the newly deployed Account.
     * @dev If accountVersion == 0, the newest version will be used.
     * @dev createAccount() uses the CREATE2 opcode, which can lead to address collision vulnerabilities,
     * as described in: https://eips.ethereum.org/EIPS/eip-3607.
     * To decrease the probability of finding an address collision, the number of possible account addresses is limited to 2**64.
     * We use a salt with 64 bits, the 32 right most bits of the address of the tx.origin, and 32 bits provided by the user.
     */
    function createAccount(uint32 userSalt, uint256 accountVersion, address creditor)
        external
        whenCreateNotPaused
        returns (address account)
    {
        accountVersion = accountVersion == 0 ? latestAccountVersion : accountVersion;

        if (accountVersion > latestAccountVersion) revert FactoryErrors.InvalidAccountVersion();
        if (accountVersionBlocked[accountVersion]) revert FactoryErrors.AccountVersionBlocked();

        // Hash tx.origin with the user provided salt to avoid front-running Account deployment with an identical salt.
        // We use tx.origin instead of msg.sender so that deployments through third party contracts are not vulnerable to front-running.
        // 64 bit salt: 32 bits from tx.origin and 32 bits provided by the user.
        uint256 salt = uint256(keccak256(abi.encodePacked(userSalt, uint32(uint160(tx.origin)))));
        account = CreateProxyLib.createProxy(salt, versionInformation[accountVersion].implementation);

        allAccounts.push(account);
        accountIndex[account] = allAccounts.length;

        _mint(msg.sender, allAccounts.length);

        IAccount(account).initialize(msg.sender, versionInformation[accountVersion].registry, creditor);

        // unsafe cast: accountVersion <= latestAccountVersion, which is a uint88.
        // forge-lint: disable-next-line(unsafe-typecast)
        emit AccountUpgraded(account, uint88(accountVersion));
    }

    /**
     * @notice View function returning if an address is an Account.
     * @param account The address to be checked.
     * @return bool Whether the address is an Account or not.
     */
    function isAccount(address account) public view returns (bool) {
        return accountIndex[account] > 0;
    }

    /**
     * @notice Returns the owner of an Account.
     * @param account The Account address.
     * @return owner_ The Account owner.
     * @dev Function does not revert when a non-existing Account is passed, but returns zero-address as owner.
     */
    function ownerOfAccount(address account) external view returns (address owner_) {
        owner_ = _ownerOf[accountIndex[account]];
    }

    /**
     * @notice This function allows Account owners to upgrade the implementation of the Account.
     * @param account Account that needs to be upgraded.
     * @param version The accountVersion to upgrade to.
     * @param proofs The Merkle proofs that prove the compatibility of the upgrade from current to new account version.
     * @dev As each Account is a proxy, the implementation of the proxy can be changed by the owner of the Account.
     * Checks are done such that only compatible versions can be upgraded to.
     * Merkle proofs and their leaves can be found on https://www.github.com/arcadia-finance.
     */
    function upgradeAccountVersion(address account, uint256 version, bytes32[] calldata proofs) external {
        if (_ownerOf[accountIndex[account]] != msg.sender) revert FactoryErrors.OnlyAccountOwner();
        if (accountVersionBlocked[version]) revert FactoryErrors.AccountVersionBlocked();

        uint256 currentVersion = IAccount(account).ACCOUNT_VERSION();
        bool canUpgrade =
            MerkleProofLib.verify(proofs, versionRoot, keccak256(abi.encodePacked(currentVersion, version)));

        if (!canUpgrade) revert FactoryErrors.InvalidUpgrade();

        IAccount(account)
            .upgradeAccount(
                versionInformation[version].implementation,
                versionInformation[version].registry,
                version,
                versionInformation[version].data
            );

        // unsafe cast: accountVersion <= latestAccountVersion, which is a uint88.
        // forge-lint: disable-next-line(unsafe-typecast)
        emit AccountUpgraded(account, uint88(version));
    }

    /**
     * @notice Function used to transfer an Account between users based on Account address.
     * @param from The sender.
     * @param to The target.
     * @param account The address of the Account that is transferred.
     * @dev This method transfers an Account on Account address instead of id and
     * also transfers the Account proxy contract to the new owner.
     * @dev The Account itself cannot become its owner.
     */
    function safeTransferFrom(address from, address to, address account) public {
        if (to == account) revert FactoryErrors.InvalidRecipient();

        uint256 id = accountIndex[account];
        IAccount(allAccounts[id - 1]).transferOwnership(to);
        super.safeTransferFrom(from, to, id);
    }

    /**
     * @notice Function used to transfer an Account between users based on Account id.
     * @param from The sender.
     * @param to The target.
     * @param id The id of the Account that is about to be transferred.
     * @dev This method overwrites the safeTransferFrom function in ERC721.sol to
     * also transfer the Account proxy contract to the new owner.
     * @dev The Account itself cannot become its owner.
     */
    function safeTransferFrom(address from, address to, uint256 id) public override {
        address account = allAccounts[id - 1];
        if (to == account) revert FactoryErrors.InvalidRecipient();

        IAccount(account).transferOwnership(to);
        super.safeTransferFrom(from, to, id);
    }

    /**
     * @notice Function used to transfer an Account between users based on Account id.
     * @param from The sender.
     * @param to The target.
     * @param id The id of the Account that is about to be transferred.
     * @param data additional data, only used for onERC721Received.
     * @dev This method overwrites the safeTransferFrom function in ERC721.sol to
     * also transfer the Account proxy contract to the new owner.
     * @dev The Account itself cannot become its owner.
     */
    function safeTransferFrom(address from, address to, uint256 id, bytes calldata data) public override {
        address account = allAccounts[id - 1];
        if (to == account) revert FactoryErrors.InvalidRecipient();

        IAccount(account).transferOwnership(to);
        super.safeTransferFrom(from, to, id, data);
    }

    /**
     * @notice Function used to transfer an Account between users based on Account id.
     * @param from The sender.
     * @param to The target.
     * @param id The id of the Account that is about to be transferred.
     * @dev This method overwrites the transferFrom function in ERC721.sol to
     * also transfer the Account proxy contract to the new owner.
     * @dev The Account itself cannot become its owner.
     */
    function transferFrom(address from, address to, uint256 id) public override {
        address account = allAccounts[id - 1];
        if (to == account) revert FactoryErrors.InvalidRecipient();

        IAccount(account).transferOwnership(to);
        // forge-lint: disable-next-line(erc20-unchecked-transfer)
        super.transferFrom(from, to, id);
    }

    /**
     * @notice Function used to transfer an Account, called by the Account itself.
     * @param to The target.
     * @dev Adaptation of safeTransferFrom from the ERC-721 standard, where the Account itself triggers the transfer.
     * @dev The Account must do the transferOwnership() before calling this function.
     * @dev The Account itself cannot become its owner.
     */
    function safeTransferAccount(address to) public {
        if (to == address(0)) revert FactoryErrors.InvalidRecipient();
        if (to == msg.sender) revert FactoryErrors.InvalidRecipient();

        uint256 id = accountIndex[msg.sender];
        if (id == 0) revert FactoryErrors.OnlyAccount();

        address from = _ownerOf[id];

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        unchecked {
            _balanceOf[from]--;
            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        delete getApproved[id];

        if (
            to.code.length != 0
                && ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "")
                    != ERC721TokenReceiver.onERC721Received.selector
        ) revert FactoryErrors.UnsafeRecipient();

        emit Transfer(from, to, id);
    }

    /*///////////////////////////////////////////////////////////////
                    ACCOUNT VERSION MANAGEMENT
    ///////////////////////////////////////////////////////////////*/

    /**
     * @notice Function to set a new Account version with the contracts to be used for new deployed Accounts.
     * @param registry The contract address of the Registry.
     * @param implementation The contract address of the Account implementation.
     * @param versionRoot_ The Merkle root of the Merkle tree of all the compatible Account versions.
     * @param data Arbitrary data, can contain instructions to execute when updating Account to new implementation.
     * @dev Changing any of the contracts does NOT change the contracts for existing deployed Accounts,
     * unless the Account owner explicitly chooses to upgrade their Account to a newer version.
     */
    function setNewAccountInfo(address registry, address implementation, bytes32 versionRoot_, bytes calldata data)
        external
        onlyOwner
    {
        if (versionRoot_ == bytes32(0)) revert FactoryErrors.VersionRootIsZero();
        if (implementation == address(0)) revert FactoryErrors.ImplIsZero();

        uint256 latestAccountVersion_;
        unchecked {
            // Update and cache the new latestAccountVersion.
            latestAccountVersion_ = ++latestAccountVersion;
        }

        versionRoot = versionRoot_;
        versionInformation[latestAccountVersion_] =
            VersionInformation({ registry: registry, implementation: implementation, data: data });

        if (IAccount(implementation).ACCOUNT_VERSION() != latestAccountVersion) revert FactoryErrors.VersionMismatch();
        if (IAccount(implementation).FACTORY() != address(this)) revert FactoryErrors.FactoryMismatch();
        if (IRegistry(registry).FACTORY() != address(this)) revert FactoryErrors.FactoryMismatch();

        // forge-lint: disable-next-line(unsafe-typecast)
        emit AccountVersionAdded(uint88(latestAccountVersion_), registry, implementation);
    }

    /**
     * @notice Function to block a certain Account implementation version from being created as a new Account.
     * @param version The Account version to be phased out.
     * @dev Should any Account implementation version be phased out,
     * this function can be used to block it from being created for new Accounts.
     * @dev Although possible to block an Account version through the versionRoot,
     * that would require verifying the Merkle tree on account creation, which is expensive.
     */
    function blockAccountVersion(uint256 version) external onlyOwner {
        if (version == 0 || version > latestAccountVersion) revert FactoryErrors.InvalidAccountVersion();
        accountVersionBlocked[version] = true;

        // unsafe cast: accountVersion <= latestAccountVersion, which is a uint88.
        // forge-lint: disable-next-line(unsafe-typecast)
        emit AccountVersionBlocked(uint88(version));
    }

    /*///////////////////////////////////////////////////////////////
                        HELPER FUNCTIONS
    ///////////////////////////////////////////////////////////////*/

    /**
     * @notice Function returns the total number of Accounts.
     * @return numberOfAccounts The total number of Accounts.
     */
    function allAccountsLength() external view returns (uint256 numberOfAccounts) {
        numberOfAccounts = allAccounts.length;
    }

    /**
     * @notice Computes the address of a new Account.
     * @param user The address of the user (tx.origin) creating the Account.
     * @param userSalt A salt, provided by the user, to generate the Account address.
     * @param accountVersion The Account version.
     * @return account The contract address of the Proxy of the new Account.
     * @dev Does not verify if the account version exists or is blocked.
     */
    function getAccountAddress(address user, uint32 userSalt, uint256 accountVersion)
        external
        view
        returns (address account)
    {
        accountVersion = accountVersion == 0 ? latestAccountVersion : accountVersion;

        // forge-lint: disable-next-line(unsafe-typecast)
        uint256 salt = uint256(keccak256(abi.encodePacked(userSalt, uint32(uint160(user)))));
        account = CreateProxyLib.getProxyAddress(salt, versionInformation[accountVersion].implementation);
    }

    /*///////////////////////////////////////////////////////////////
                        ERC-721 LOGIC
    ///////////////////////////////////////////////////////////////*/

    /**
     * @notice Function that stores a new base URI.
     * @param newBaseURI The new base URI to store.
     * @dev tokenURIs of Arcadia Accounts are not meant to be immutable
     * and might be updated later to allow users to choose/create their own Account art,
     * as such no URI freeze is added.
     */
    // forge-lint: disable-next-item(mixed-case-function,mixed-case-variable)
    function setBaseURI(string calldata newBaseURI) external onlyOwner {
        baseURI = newBaseURI;
    }

    /**
     * @notice Function that returns the token URI as defined in the ERC721 standard.
     * @param tokenId The id of the Account.
     * @return uri The token URI.
     */
    // forge-lint: disable-next-item(mixed-case-function,mixed-case-variable)
    function tokenURI(uint256 tokenId) public view override returns (string memory uri) {
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }
}

/**
 * Created by Pragma Labs
 * SPDX-License-Identifier: BUSL-1.1
 */
pragma solidity ^0.8.0;

/**
 * @title Library for creating Arcadia Proxy Contracts
 * @author Pragma Labs
 */
library CreateProxyLib {
    /* //////////////////////////////////////////////////////////////
                                CONSTANTS
    ////////////////////////////////////////////////////////////// */

    // The bytecode of the Proxy contract.
    bytes internal constant PROXY_BYTECODE =
        hex"608060405260405161017c38038061017c8339810160408190526100229161008d565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0383169081179091556040517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2506100ba565b5f6020828403121561009d575f80fd5b81516001600160a01b03811681146100b3575f80fd5b9392505050565b60b6806100c65f395ff3fe608060405236603c57603a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b546001600160a01b03166063565b005b603a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc602c565b365f80375f80365f845af43d5f803e808015607c573d5ff35b3d5ffdfea2646970667358221220eeb8a2fa918a2057b66e1d3fa3930647dc7a4e56c99898cd9e280beec9d9ba9f64736f6c63430008160033000000000000000000000000";

    /* //////////////////////////////////////////////////////////////
                                ERRORS
    ////////////////////////////////////////////////////////////// */

    error ProxyCreationFailed();

    /* //////////////////////////////////////////////////////////////
                            CREATION LOGIC
    ////////////////////////////////////////////////////////////// */

    /**
     * @notice Creates a new Proxy.
     * @param salt The create2 salt.
     * @param implementation The implementation contract of the Proxy.
     * @return proxy The contract address of the Proxy.
     */
    function createProxy(uint256 salt, address implementation) internal returns (address proxy) {
        bytes memory runtimeBytecode = abi.encodePacked(PROXY_BYTECODE, implementation);
        assembly {
            proxy := create2(0, add(runtimeBytecode, 0x20), mload(runtimeBytecode), salt)
        }
        if (proxy.code.length == 0) revert ProxyCreationFailed();
    }

    /**
     * @notice Computes the address of a Proxy contract.
     * @param salt The create2 salt.
     * @param implementation The implementation contract of the Proxy.
     * @return proxy The contract address of the Proxy.
     */
    function getProxyAddress(uint256 salt, address implementation) internal view returns (address proxy) {
        bytes memory runtimeBytecode = abi.encodePacked(PROXY_BYTECODE, implementation);
        proxy = address(
            uint160(uint256(keccak256(abi.encodePacked(hex"ff", address(this), salt, keccak256(runtimeBytecode)))))
        );
    }
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern, minimalist, and gas efficient ERC-721 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 indexed id);

    event Approval(address indexed owner, address indexed spender, uint256 indexed id);

    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /*//////////////////////////////////////////////////////////////
                         METADATA STORAGE/LOGIC
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    function tokenURI(uint256 id) public view virtual returns (string memory);

    /*//////////////////////////////////////////////////////////////
                      ERC721 BALANCE/OWNER STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) internal _ownerOf;

    mapping(address => uint256) internal _balanceOf;

    function ownerOf(uint256 id) public view virtual returns (address owner) {
        require((owner = _ownerOf[id]) != address(0), "NOT_MINTED");
    }

    function balanceOf(address owner) public view virtual returns (uint256) {
        require(owner != address(0), "ZERO_ADDRESS");

        return _balanceOf[owner];
    }

    /*//////////////////////////////////////////////////////////////
                         ERC721 APPROVAL STORAGE
    //////////////////////////////////////////////////////////////*/

    mapping(uint256 => address) public getApproved;

    mapping(address => mapping(address => bool)) public isApprovedForAll;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(string memory _name, string memory _symbol) {
        name = _name;
        symbol = _symbol;
    }

    /*//////////////////////////////////////////////////////////////
                              ERC721 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 id) public virtual {
        address owner = _ownerOf[id];

        require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED");

        getApproved[id] = spender;

        emit Approval(owner, spender, id);
    }

    function setApprovalForAll(address operator, bool approved) public virtual {
        isApprovedForAll[msg.sender][operator] = approved;

        emit ApprovalForAll(msg.sender, operator, approved);
    }

    function transferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        require(from == _ownerOf[id], "WRONG_FROM");

        require(to != address(0), "INVALID_RECIPIENT");

        require(
            msg.sender == from || isApprovedForAll[from][msg.sender] || msg.sender == getApproved[id],
            "NOT_AUTHORIZED"
        );

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        unchecked {
            _balanceOf[from]--;

            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        delete getApproved[id];

        emit Transfer(from, to, id);
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        bytes calldata data
    ) public virtual {
        transferFrom(from, to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    /*//////////////////////////////////////////////////////////////
                              ERC165 LOGIC
    //////////////////////////////////////////////////////////////*/

    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return
            interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165
            interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721
            interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 id) internal virtual {
        require(to != address(0), "INVALID_RECIPIENT");

        require(_ownerOf[id] == address(0), "ALREADY_MINTED");

        // Counter overflow is incredibly unrealistic.
        unchecked {
            _balanceOf[to]++;
        }

        _ownerOf[id] = to;

        emit Transfer(address(0), to, id);
    }

    function _burn(uint256 id) internal virtual {
        address owner = _ownerOf[id];

        require(owner != address(0), "NOT_MINTED");

        // Ownership check above ensures no underflow.
        unchecked {
            _balanceOf[owner]--;
        }

        delete _ownerOf[id];

        delete getApproved[id];

        emit Transfer(owner, address(0), id);
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL SAFE MINT LOGIC
    //////////////////////////////////////////////////////////////*/

    function _safeMint(address to, uint256 id) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }

    function _safeMint(
        address to,
        uint256 id,
        bytes memory data
    ) internal virtual {
        _mint(to, id);

        require(
            to.code.length == 0 ||
                ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) ==
                ERC721TokenReceiver.onERC721Received.selector,
            "UNSAFE_RECIPIENT"
        );
    }
}

/// @notice A generic interface for a contract which properly accepts ERC721 tokens.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol)
abstract contract ERC721TokenReceiver {
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC721TokenReceiver.onERC721Received.selector;
    }
}

/**
 * Created by Pragma Labs
 * SPDX-License-Identifier: BUSL-1.1
 */
pragma solidity ^0.8.0;

library AccountErrors {
    error AccountInAuction();
    error AccountNotLiquidatable();
    error AccountUnhealthy();
    error AlreadyInitialized();
    error CreditorAlreadySet();
    error CreditorNotSet();
    error CoolDownPeriodNotPassed();
    error InvalidAccountVersion();
    error InvalidERC20Id();
    error InvalidERC721Amount();
    error InvalidRecipient();
    error InvalidRegistry();
    error InvalidUpgrade();
    error LengthMismatch();
    error NoFallback();
    error NoReentry();
    error NonZeroOpenPosition();
    error NumeraireNotFound();
    error OnlyCreditor();
    error OnlyFactory();
    error OnlyLiquidator();
    error OnlyOwner();
    error OnlySelf();
    error TooManyAssets();
    error UnknownAsset();
    error UnknownAssetType();
}

library FactoryErrors {
    error AccountCreationFailed();
    error AccountVersionBlocked();
    error FactoryMismatch();
    error InvalidAccountVersion();
    error InvalidRecipient();
    error InvalidUpgrade();
    error ImplIsZero();
    error OnlyAccount();
    error OnlyAccountOwner();
    error UnsafeRecipient();
    error VersionMismatch();
    error VersionRootIsZero();
}

library GuardianErrors {
    // Thrown when the cool-down period has not yet passed.
    error CoolDownPeriodNotPassed();
    // Thrown when the functionality is paused.
    error FunctionIsPaused();
    // Thrown when the caller is not the Guardian.
    error OnlyGuardian();
}

library RegistryErrors {
    error AssetAlreadyInRegistry();
    error AssetModNotUnique();
    error AssetNotAllowed();
    error InvalidAssetType();
    error LengthMismatch();
    error MaxRecursiveCallsReached();
    error Min1Oracle();
    error OnlyAccount();
    error OnlyAssetModule();
    error OnlyOracleModule();
    error OracleModNotUnique();
    error OracleNotReverting();
    error OracleReverting();
    error SequencerDown();
    error Unauthorized();
    error UnknownAsset();
}

/**
 * Created by Pragma Labs
 * SPDX-License-Identifier: BUSL-1.1
 */
pragma solidity ^0.8.0;

import { BaseGuardian, GuardianErrors } from "./BaseGuardian.sol";

/**
 * @title Factory Guardian
 * @author Pragma Labs
 * @notice Logic inherited by the Factory that allows:
 * - An authorized guardian to trigger an emergency stop.
 * - The protocol owner to unpause functionalities.
 */
abstract contract FactoryGuardian is BaseGuardian {
    /* //////////////////////////////////////////////////////////////
                                STORAGE
    ////////////////////////////////////////////////////////////// */

    // Flag indicating if the create() function is paused.
    bool public createPaused;

    /* //////////////////////////////////////////////////////////////
                                ERRORS
    ////////////////////////////////////////////////////////////// */

    error FunctionNotImplemented();

    /* //////////////////////////////////////////////////////////////
                                EVENTS
    ////////////////////////////////////////////////////////////// */

    event PauseFlagsUpdated(bool createPauseUpdate);

    /* //////////////////////////////////////////////////////////////
                                MODIFIERS
    ////////////////////////////////////////////////////////////// */

    /**
     * @dev Throws if the createAccount functionality is paused.
     */
    modifier whenCreateNotPaused() {
        if (createPaused) revert GuardianErrors.FunctionIsPaused();
        _;
    }

    /* //////////////////////////////////////////////////////////////
                                CONSTRUCTOR
    ////////////////////////////////////////////////////////////// */

    /**
     * @param owner_ The address of the Owner.
     */
    constructor(address owner_) BaseGuardian(owner_) { }

    /* //////////////////////////////////////////////////////////////
                            PAUSING LOGIC
    ////////////////////////////////////////////////////////////// */

    /**
     * @notice This function is used to pause the creation of Accounts.
     * @dev The pause guardian of the Factory has no cool-down period.
     */
    function pause() external override onlyGuardian {
        emit PauseFlagsUpdated(createPaused = true);
    }

    /**
     * @notice This function is used to unpause the creation of Accounts.
     * @param createPaused_ "False" when create functionality should be unpaused.
     * @dev This function can unpause the creation of new Accounts.
     * @dev Can only update flags from paused (true) to unpaused (false), cannot be used the other way around
     * (to set unpaused flags to paused).
     */
    function unpause(bool createPaused_) external onlyOwner {
        emit PauseFlagsUpdated(createPaused = createPaused && createPaused_);
    }

    /**
     * @notice This function is not implemented.
     * @dev No reason to be able to create an Account if the owner of the Factory did not unpause createAccount().
     */
    function unpause() external pure override {
        revert FunctionNotImplemented();
    }
}

/**
 * Created by Pragma Labs
 * SPDX-License-Identifier: MIT
 */
pragma solidity ^0.8.0;

// forge-lint: disable-next-item(mixed-case-function)
interface IAccount {
    /**
     * @notice Returns the Account version.
     * @return version The Account version.
     */
    function ACCOUNT_VERSION() external view returns (uint256);

    /**
     * @notice Returns the Arcadia Accounts Factory.
     * @return factory The contract address of the Arcadia Accounts Factory.
     */
    function FACTORY() external view returns (address);

    /**
     * @notice Initiates the variables of the Account.
     * @param owner The sender of the 'createAccount' on the factory
     * @param registry The 'beacon' contract with the external logic.
     * @param creditor The contract address of the creditor.
     */
    function initialize(address owner, address registry, address creditor) external;

    /**
     * @notice Updates the Account version and stores a new address in the EIP1967 implementation slot.
     * @param newImplementation The contract with the new Account logic.
     * @param newRegistry The Registry for this specific implementation (might be identical as the old registry).
     * @param data Arbitrary data, can contain instructions to execute when updating Account to new logic.
     * @param newVersion The new version of the Account logic.
     */
    function upgradeAccount(address newImplementation, address newRegistry, uint256 newVersion, bytes calldata data)
        external;

    /**
     * @notice Transfers ownership of the contract to a new account.
     * @param newOwner The new owner of the Account.
     */
    function transferOwnership(address newOwner) external;
}

/**
 * Created by Pragma Labs
 * SPDX-License-Identifier: MIT
 */
pragma solidity ^0.8.0;

interface IFactory {
    /**
     * @notice Checks if a contract is an Account.
     * @param account The contract address of the Account.
     * @return bool indicating if the address is an Account or not.
     */
    function isAccount(address account) external view returns (bool);

    /**
     * @notice Function used to transfer an Account, called by the Account itself.
     * @param to The target.
     */
    function safeTransferAccount(address to) external;

    /**
     * @notice Function used to transfer an Account between users based on Account address.
     * @param from The sender.
     * @param to The target.
     * @param account The address of the Account that is transferred.
     * @dev This method transfers an Account on Account address instead of id and
     * also transfers the Account proxy contract to the new owner.
     * @dev The Account itself cannot become its owner.
     */
    function safeTransferFrom(address from, address to, address account) external;

    /**
     * @notice This function allows Account owners to upgrade the implementation of the Account.
     * @param account Account that needs to be upgraded.
     * @param version The accountVersion to upgrade to.
     * @param proofs The Merkle proofs that prove the compatibility of the upgrade from current to new account version.
     * @dev As each Account is a proxy, the implementation of the proxy can be changed by the owner of the Account.
     * Checks are done such that only compatible versions can be upgraded to.
     * Merkle proofs and their leaves can be found on https://www.github.com/arcadia-finance.
     */
    function upgradeAccountVersion(address account, uint256 version, bytes32[] calldata proofs) external;
}

/**
 * Created by Pragma Labs
 * SPDX-License-Identifier: MIT
 */
pragma solidity ^0.8.0;

import { AssetValueAndRiskFactors } from "../libraries/AssetValuationLib.sol";

interface IRegistry {
    /**
     * @notice Returns the Arcadia Accounts Factory.
     * @return factory The contract address of the Arcadia Accounts Factory.
     */
    // forge-lint: disable-next-item(mixed-case-function)
    function FACTORY() external view returns (address);

    /**
     * @notice Checks if an asset is in the Registry.
     * @param asset The contract address of the asset.
     * @return boolean.
     */
    function inRegistry(address asset) external view returns (bool);

    /**
     * @notice Batch retrieves the asset types.
     * @param assetAddresses Array of the contract addresses of the assets.
     * @return assetTypes Array with the types of the assets.
     * 0 = Unknown asset.
     * 1 = ERC20.
     * 2 = ERC721.
     * 3 = ERC1155.
     * ...
     */
    function batchGetAssetTypes(address[] calldata assetAddresses) external view returns (uint256[] memory);

    /**
     * @notice Batch deposit multiple assets.
     * @param creditor The contract address of the creditor.
     * @param assetAddresses Array of the contract addresses of the assets.
     * @param assetIds Array of the IDs of the assets.
     * @param amounts Array with the amounts of the assets.
     */
    function batchProcessDeposit(
        address creditor,
        address[] calldata assetAddresses,
        uint256[] calldata assetIds,
        uint256[] calldata amounts
    ) external;

    /**
     * @notice Batch withdraw multiple assets.
     * @param creditor The contract address of the creditor.
     * @param assetAddresses Array of the contract addresses of the assets.
     * @param assetIds Array of the IDs of the assets.
     * @param amounts Array with the amounts of the assets.
     * @return assetTypes Array with the types of the assets.
     * 0 = Unknown asset.
     * 1 = ERC20.
     * 2 = ERC721.
     * 3 = ERC1155.
     */
    function batchProcessWithdrawal(
        address creditor,
        address[] calldata assetAddresses,
        uint256[] calldata assetIds,
        uint256[] calldata amounts
    ) external returns (uint256[] memory);

    /**
     * @notice Calculates the combined value of a combination of assets, denominated in a given Numeraire.
     * @param numeraire The contract address of the Numeraire.
     * @param creditor The contract address of the creditor.
     * @param assetAddresses Array of the contract addresses of the assets.
     * @param assetIds Array of the IDs of the assets.
     * @param assetAmounts Array with the amounts of the assets.
     * @return assetValue The combined value of the assets, denominated in the Numeraire.
     */
    function getTotalValue(
        address numeraire,
        address creditor,
        address[] calldata assetAddresses,
        uint256[] calldata assetIds,
        uint256[] calldata assetAmounts
    ) external view returns (uint256);

    /**
     * @notice Calculates the collateralValue of a combination of assets, denominated in a given Numeraire.
     * @param numeraire The contract address of the Numeraire.
     * @param creditor The contract address of the creditor.
     * @param assetAddresses Array of the contract addresses of the assets.
     * @param assetIds Array of the IDs of the assets.
     * @param assetAmounts Array with the amounts of the assets.
     * @return collateralValue The collateral value of the assets, denominated in the Numeraire.
     */
    function getCollateralValue(
        address numeraire,
        address creditor,
        address[] calldata assetAddresses,
        uint256[] calldata assetIds,
        uint256[] calldata assetAmounts
    ) external view returns (uint256);

    /**
     * @notice Calculates the getLiquidationValue of a combination of assets, denominated in a given Numeraire.
     * @param numeraire The contract address of the Numeraire.
     * @param creditor The contract address of the creditor.
     * @param assetAddresses Array of the contract addresses of the assets.
     * @param assetIds Array of the IDs of the assets.
     * @param assetAmounts Array with the amounts of the assets.
     * @return liquidationValue The liquidation value of the assets, denominated in the Numeraire.
     */
    function getLiquidationValue(
        address numeraire,
        address creditor,
        address[] calldata assetAddresses,
        uint256[] calldata assetIds,
        uint256[] calldata assetAmounts
    ) external view returns (uint256);

    /**
     * @notice Calculates the values per asset, denominated in a given Numeraire.
     * @param numeraire The contract address of the Numeraire.
     * @param creditor The contract address of the creditor.
     * @param assetAddresses Array of the contract addresses of the assets.
     * @param assetIds Array of the IDs of the assets.
     * @param assetAmounts Array with the amounts of the assets.
     * @return valuesAndRiskFactors The array of values per assets, denominated in the Numeraire.
     */
    function getValuesInNumeraire(
        address numeraire,
        address creditor,
        address[] calldata assetAddresses,
        uint256[] calldata assetIds,
        uint256[] calldata assetAmounts
    ) external view returns (AssetValueAndRiskFactors[] memory valuesAndRiskFactors);
}

File 9 of 13 : MerkleProofLib.sol
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @notice Gas optimized merkle proof verification library.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/MerkleProofLib.sol)
/// @author Modified from Solady (https://github.com/Vectorized/solady/blob/main/src/utils/MerkleProofLib.sol)
library MerkleProofLib {
    function verify(
        bytes32[] calldata proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool isValid) {
        /// @solidity memory-safe-assembly
        assembly {
            if proof.length {
                // Left shifting by 5 is like multiplying by 32.
                let end := add(proof.offset, shl(5, proof.length))

                // Initialize offset to the offset of the proof in calldata.
                let offset := proof.offset

                // Iterate over proof elements to compute root hash.
                // prettier-ignore
                for {} 1 {} {
                    // Slot where the leaf should be put in scratch space. If
                    // leaf > calldataload(offset): slot 32, otherwise: slot 0.
                    let leafSlot := shl(5, gt(leaf, calldataload(offset)))

                    // Store elements to hash contiguously in scratch space.
                    // The xor puts calldataload(offset) in whichever slot leaf
                    // is not occupying, so 0 if leafSlot is 32, and 32 otherwise.
                    mstore(leafSlot, leaf)
                    mstore(xor(leafSlot, 32), calldataload(offset))

                    // Reuse leaf to store the hash to reduce stack operations.
                    leaf := keccak256(0, 64) // Hash both slots of scratch space.

                    offset := add(offset, 32) // Shift 1 word per cycle.

                    // prettier-ignore
                    if iszero(lt(offset, end)) { break }
                }
            }

            isValid := eq(leaf, root) // The proof is valid if the roots match.
        }
    }
}

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity ^0.8.0;

// forge-lint: disable-next-item(unsafe-typecast)
library Strings {
    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT license
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }
}

/**
 * Created by Pragma Labs
 * SPDX-License-Identifier: BUSL-1.1
 */
pragma solidity ^0.8.0;

import { GuardianErrors } from "../libraries/Errors.sol";
import { Owned } from "../../lib/solmate/src/auth/Owned.sol";

/**
 * @title Guardian
 * @author Pragma Labs
 * @notice Abstract contract with the minimal implementation of a Guardian contract.
 * It implements the following logic:
 * - An authorized guardian can trigger an emergency stop.
 * - The protocol owner can unpause functionalities one-by-one.
 * - Anyone can unpause all functionalities after a fixed cool-down period.
 */
abstract contract BaseGuardian is Owned {
    /* //////////////////////////////////////////////////////////////
                                STORAGE
    ////////////////////////////////////////////////////////////// */

    // Last timestamp an emergency stop was triggered.
    uint96 public pauseTimestamp;
    // Address of the Guardian.
    address public guardian;

    /* //////////////////////////////////////////////////////////////
                                EVENTS
    ////////////////////////////////////////////////////////////// */

    event GuardianChanged(address indexed user, address indexed newGuardian);

    /* //////////////////////////////////////////////////////////////
                                MODIFIERS
    ////////////////////////////////////////////////////////////// */

    /**
     * @dev Only guardians can call functions with this modifier.
     */
    modifier onlyGuardian() {
        if (msg.sender != guardian) revert GuardianErrors.OnlyGuardian();
        _;
    }

    /**
     * @dev The public unpause() function, or a second pause() function, can only called a fixed coolDownPeriod after an initial pause().
     * This gives the protocol owner time to investigate and solve potential issues,
     * but ensures that no rogue owner or guardian can lock user funds for an indefinite amount of time.
     */
    modifier afterCoolDownOf(uint256 coolDownPeriod) {
        if (block.timestamp <= pauseTimestamp + coolDownPeriod) revert GuardianErrors.CoolDownPeriodNotPassed();
        _;
    }

    /* //////////////////////////////////////////////////////////////
                                CONSTRUCTOR
    ////////////////////////////////////////////////////////////// */

    /**
     * @param owner_ The address of the Owner.
     */
    constructor(address owner_) Owned(owner_) { }

    /* //////////////////////////////////////////////////////////////
                            GUARDIAN LOGIC
    ////////////////////////////////////////////////////////////// */

    /**
     * @notice This function is used to set the guardian address
     * @param guardian_ The address of the new guardian.
     */
    function changeGuardian(address guardian_) external onlyOwner {
        emit GuardianChanged(msg.sender, guardian = guardian_);
    }

    /* //////////////////////////////////////////////////////////////
                            PAUSING LOGIC
    ////////////////////////////////////////////////////////////// */

    /**
     * @notice This function is used to pause all the flags of the contract.
     * @dev The Guardian can only pause the protocol again after 32 days have passed since the last pause.
     * This is to prevent that a malicious owner or guardian can take user funds hostage for an indefinite time.
     * After the guardian has paused the protocol, the owner has 30 days to find potential problems,
     * find a solution and unpause the protocol. If the protocol is not unpaused after 30 days,
     * an emergency procedure can be started by any user to unpause the protocol.
     * All users have now at least a two-day window to withdraw assets and close positions before
     * the protocol can again be paused 32 days after the contract was previously paused.
     */
    function pause() external virtual;

    /**
     * @notice This function is used to unpause flags that could be abused to lock user assets.
     * @dev If the protocol is not unpaused after 30 days, any user can unpause the protocol.
     * This ensures that no rogue owner or guardian can lock user funds for an indefinite amount of time.
     * All users have now at least a two-day window to withdraw assets and close positions before
     * the protocol can again be paused 32 days after the contract was previously paused.
     */
    function unpause() external virtual;
}

/**
 * Created by Pragma Labs
 * SPDX-License-Identifier: BUSL-1.1
 */
pragma solidity ^0.8.0;

// Struct with risk and valuation related information for a certain asset.
struct AssetValueAndRiskFactors {
    // The value of the asset.
    uint256 assetValue;
    // The collateral factor of the asset, for a given creditor.
    uint256 collateralFactor;
    // The liquidation factor of the asset, for a given creditor.
    uint256 liquidationFactor;
}

/**
 * @title Asset Valuation Library
 * @author Pragma Labs
 * @notice The Asset Valuation Library is responsible for calculating the risk weighted values of combinations of assets.
 */
library AssetValuationLib {
    /*///////////////////////////////////////////////////////////////
                        CONSTANTS
    ///////////////////////////////////////////////////////////////*/

    uint256 internal constant ONE_4 = 10_000;

    /*///////////////////////////////////////////////////////////////
                        RISK FACTORS
    ///////////////////////////////////////////////////////////////*/

    /**
     * @notice Calculates the collateral value given a combination of asset values and corresponding collateral factors.
     * @param valuesAndRiskFactors Array of asset values and corresponding collateral factors.
     * @return collateralValue The collateral value of the given assets.
     */
    function _calculateCollateralValue(AssetValueAndRiskFactors[] memory valuesAndRiskFactors)
        internal
        pure
        returns (uint256 collateralValue)
    {
        for (uint256 i; i < valuesAndRiskFactors.length; ++i) {
            collateralValue += valuesAndRiskFactors[i].assetValue * valuesAndRiskFactors[i].collateralFactor;
        }
        collateralValue = collateralValue / ONE_4;
    }

    /**
     * @notice Calculates the liquidation value given a combination of asset values and corresponding liquidation factors.
     * @param valuesAndRiskFactors List of asset values and corresponding liquidation factors.
     * @return liquidationValue The liquidation value of the given assets.
     */
    function _calculateLiquidationValue(AssetValueAndRiskFactors[] memory valuesAndRiskFactors)
        internal
        pure
        returns (uint256 liquidationValue)
    {
        for (uint256 i; i < valuesAndRiskFactors.length; ++i) {
            liquidationValue += valuesAndRiskFactors[i].assetValue * valuesAndRiskFactors[i].liquidationFactor;
        }
        liquidationValue = liquidationValue / ONE_4;
    }
}

// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnershipTransferred(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

Settings
{
  "remappings": [
    "@ensdomains/=lib/lending-v2/lib/accounts-v2/lib/slipstream/node_modules/@ensdomains/",
    "@nomad-xyz/=lib/lending-v2/lib/accounts-v2/lib/slipstream/lib/ExcessivelySafeCall/",
    "@openzeppelin/=lib/lending-v2/lib/accounts-v2/lib/slipstream/lib/openzeppelin-contracts/",
    "@solidity-parser/=lib/lending-v2/lib/accounts-v2/lib/slipstream/node_modules/solhint/node_modules/@solidity-parser/",
    "@uniswap/v2-core/contracts/=lib/lending-v2/lib/accounts-v2/./test/utils/fixtures/swap-router-02/",
    "@uniswap/v3-core/contracts/=lib/lending-v2/lib/accounts-v2/lib/v3-core/contracts/",
    "@uniswap/v3-periphery/contracts/=lib/lending-v2/lib/accounts-v2/lib/v3-periphery/contracts/",
    "@uniswap/v4-core/=lib/lending-v2/lib/accounts-v2/lib/v4-periphery/lib/v4-core/",
    "@utils/=lib/lending-v2/lib/accounts-v2/lib/merkl-contracts/node_modules/utils/src/",
    "ExcessivelySafeCall/=lib/lending-v2/lib/accounts-v2/lib/slipstream/lib/ExcessivelySafeCall/src/",
    "accounts-v2/=lib/lending-v2/lib/accounts-v2/src/",
    "arcadia-periphery/=lib/arcadia-periphery/src/",
    "asset-managers/=lib/arcadia-periphery/lib/asset-managers/src/",
    "base64-sol/=lib/lending-v2/lib/accounts-v2/lib/slipstream/lib/base64/",
    "base64/=lib/lending-v2/lib/accounts-v2/lib/slipstream/lib/base64/",
    "contracts/=lib/lending-v2/lib/accounts-v2/lib/slipstream/contracts/",
    "ds-test/=lib/lending-v2/lib/accounts-v2/lib/solmate/lib/ds-test/src/",
    "erc4626-tests/=lib/lending-v2/lib/accounts-v2/lib/openzeppelin-contracts-v4.9/lib/erc4626-tests/",
    "forge-gas-snapshot/=lib/lending-v2/lib/accounts-v2/lib/v4-periphery/lib/permit2/lib/forge-gas-snapshot/src/",
    "forge-std/=lib/lending-v2/lib/accounts-v2/lib/forge-std/src/",
    "hardhat/=lib/lending-v2/lib/accounts-v2/lib/slipstream/node_modules/hardhat/",
    "lending-v2/=lib/lending-v2/src/",
    "merkl-contracts/=lib/lending-v2/lib/accounts-v2/lib/merkl-contracts/",
    "openzeppelin-contracts-upgradeable-v4.9/=lib/lending-v2/lib/accounts-v2/lib/openzeppelin-contracts-upgradeable-v4.9/",
    "openzeppelin-contracts-v3.4/=lib/lending-v2/lib/accounts-v2/lib/openzeppelin-contracts-v3.4/contracts/",
    "openzeppelin-contracts-v4.9/=lib/lending-v2/lib/accounts-v2/lib/openzeppelin-contracts-v4.9/",
    "openzeppelin-contracts/=lib/lending-v2/lib/accounts-v2/lib/slipstream/lib/openzeppelin-contracts/contracts/",
    "openzeppelin/=lib/lending-v2/lib/accounts-v2/lib/openzeppelin-contracts-v4.9/contracts/",
    "oz/=lib/lending-v2/lib/accounts-v2/lib/merkl-contracts/node_modules/@openzeppelin/contracts/",
    "permit2/=lib/lending-v2/lib/accounts-v2/lib/v4-periphery/lib/permit2/",
    "slipstream/=lib/lending-v2/lib/accounts-v2/lib/slipstream/",
    "solady/=lib/lending-v2/lib/accounts-v2/lib/solady/src/",
    "solidity-lib/=lib/lending-v2/lib/accounts-v2/lib/slipstream/lib/solidity-lib/contracts/",
    "solmate/=lib/lending-v2/lib/accounts-v2/lib/solmate/",
    "swap-router-contracts/=lib/lending-v2/lib/accounts-v2/lib/swap-router-contracts/contracts/",
    "v3-core/=lib/lending-v2/lib/accounts-v2/lib/v3-core/",
    "v3-periphery/=lib/lending-v2/lib/accounts-v2/lib/v3-periphery/contracts/",
    "v4-core/=lib/lending-v2/lib/accounts-v2/lib/v4-periphery/lib/v4-core/src/",
    "v4-periphery/=lib/lending-v2/lib/accounts-v2/lib/v4-periphery/",
    "lib/accounts-v2/lib/merkl-contracts:@openzeppelin/contracts-upgradeable/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/openzeppelin-contracts-upgradeable-v4.9/contracts/",
    "lib/accounts-v2/lib/merkl-contracts:@openzeppelin/contracts/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/openzeppelin-contracts-v4.9/contracts/",
    "lib/accounts-v2/lib/openzeppelin-contracts-upgradeable-v4.9:@openzeppelin/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/openzeppelin-contracts-v4.9/",
    "lib/accounts-v2/lib/slipstream:@openzeppelin/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/slipstream/lib/openzeppelin-contracts/",
    "lib/accounts-v2/lib/swap-router-contracts:@openzeppelin/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/openzeppelin-contracts-v3.4/",
    "lib/accounts-v2/lib/v3-periphery:@openzeppelin/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/openzeppelin-contracts-v3.4/",
    "lib/accounts-v2/lib/v4-periphery:@openzeppelin/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/",
    "lib/accounts-v2/lib/v4-periphery/lib/v4-core:@openzeppelin/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/",
    "lib/asset-managers/lib/accounts-v2/lib/slipstream:@openzeppelin/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/slipstream/lib/openzeppelin-contracts/",
    "lib/asset-managers/lib/accounts-v2/lib/swap-router-contracts:@openzeppelin/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/openzeppelin-contracts-v3.4/",
    "lib/asset-managers/lib/accounts-v2/lib/v3-periphery:@openzeppelin/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/openzeppelin-contracts-v3.4/",
    "lib/asset-managers/lib/accounts-v2/lib/v4-periphery:@openzeppelin/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/",
    "lib/asset-managers/lib/accounts-v2/lib/v4-periphery/lib/v4-core:@openzeppelin/=lib/arcadia-periphery/lib/asset-managers/lib/accounts-v2/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/",
    "lib/merkl-contracts:@openzeppelin/contracts-upgradeable/=lib/lending-v2/lib/accounts-v2/lib/openzeppelin-contracts-upgradeable-v4.9/contracts/",
    "lib/merkl-contracts:@openzeppelin/contracts/=lib/lending-v2/lib/accounts-v2/lib/openzeppelin-contracts-v4.9/contracts/",
    "lib/openzeppelin-contracts-upgradeable-v4.9:@openzeppelin/=lib/lending-v2/lib/accounts-v2/lib/openzeppelin-contracts-v4.9/",
    "lib/slipstream:@openzeppelin/=lib/lending-v2/lib/accounts-v2/lib/slipstream/lib/openzeppelin-contracts/",
    "lib/v3-periphery:@openzeppelin/=lib/lending-v2/lib/accounts-v2/lib/openzeppelin-contracts-v3.4/",
    "lib/v4-periphery:@openzeppelin/=lib/lending-v2/lib/accounts-v2/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/",
    "lib/v4-periphery/lib/v4-core:@openzeppelin/=lib/lending-v2/lib/accounts-v2/lib/v4-periphery/lib/v4-core/lib/openzeppelin-contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "prague",
  "viaIR": false
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccountVersionBlocked","type":"error"},{"inputs":[],"name":"FactoryMismatch","type":"error"},{"inputs":[],"name":"FunctionIsPaused","type":"error"},{"inputs":[],"name":"FunctionNotImplemented","type":"error"},{"inputs":[],"name":"ImplIsZero","type":"error"},{"inputs":[],"name":"InvalidAccountVersion","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidUpgrade","type":"error"},{"inputs":[],"name":"OnlyAccount","type":"error"},{"inputs":[],"name":"OnlyAccountOwner","type":"error"},{"inputs":[],"name":"OnlyGuardian","type":"error"},{"inputs":[],"name":"ProxyCreationFailed","type":"error"},{"inputs":[],"name":"UnsafeRecipient","type":"error"},{"inputs":[],"name":"VersionMismatch","type":"error"},{"inputs":[],"name":"VersionRootIsZero","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"accountAddress","type":"address"},{"indexed":true,"internalType":"uint88","name":"newVersion","type":"uint88"}],"name":"AccountUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint88","name":"version","type":"uint88"},{"indexed":true,"internalType":"address","name":"registry","type":"address"},{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"AccountVersionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint88","name":"version","type":"uint88"}],"name":"AccountVersionBlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newGuardian","type":"address"}],"name":"GuardianChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"createPauseUpdate","type":"bool"}],"name":"PauseFlagsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"accountIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"accountVersionBlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allAccounts","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allAccountsLength","outputs":[{"internalType":"uint256","name":"numberOfAccounts","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"version","type":"uint256"}],"name":"blockAccountVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"guardian_","type":"address"}],"name":"changeGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"userSalt","type":"uint32"},{"internalType":"uint256","name":"accountVersion","type":"uint256"},{"internalType":"address","name":"creditor","type":"address"}],"name":"createAccount","outputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"createPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint32","name":"userSalt","type":"uint32"},{"internalType":"uint256","name":"accountVersion","type":"uint256"}],"name":"getAccountAddress","outputs":[{"internalType":"address","name":"account","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isAccount","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAccountVersion","outputs":[{"internalType":"uint88","name":"","type":"uint88"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"ownerOfAccount","outputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pauseTimestamp","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"safeTransferAccount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"registry","type":"address"},{"internalType":"address","name":"implementation","type":"address"},{"internalType":"bytes32","name":"versionRoot_","type":"bytes32"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setNewAccountInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"uri","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bool","name":"createPaused_","type":"bool"}],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"version","type":"uint256"},{"internalType":"bytes32[]","name":"proofs","type":"bytes32[]"}],"name":"upgradeAccountVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"versionInformation","outputs":[{"internalType":"address","name":"registry","type":"address"},{"internalType":"address","name":"implementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"versionRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"}]

608060405234801561000f575f5ffd5b50604051612e6a380380612e6a83398101604081905261002e916100ea565b8080806040518060400160405280600f81526020016e105c98d8591a58481058d8dbdd5b9d608a1b815250604051806040016040528060078152602001664152434144494160c81b815250815f908161008791906101af565b50600161009482826101af565b5050600680546001600160a01b0319166001600160a01b0384169081179091556040519091505f907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350505050610269565b5f602082840312156100fa575f5ffd5b81516001600160a01b0381168114610110575f5ffd5b9392505050565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168061013f57607f821691505b60208210810361015d57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156101aa57805f5260205f20601f840160051c810160208510156101885750805b601f840160051c820191505b818110156101a7575f8155600101610194565b50505b505050565b81516001600160401b038111156101c8576101c8610117565b6101dc816101d6845461012b565b84610163565b6020601f82116001811461020e575f83156101f75750848201515b5f19600385901b1c1916600184901b1784556101a7565b5f84815260208120601f198516915b8281101561023d578785015182556020948501946001909201910161021d565b508482101561025a57868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b612bf4806102765f395ff3fe608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80637ccd031511610135578063bac7b497116100b4578063e985e9c511610079578063e985e9c51461058b578063f2fde38b146105b8578063f7ac6490146105cb578063fa807239146105de578063fa907c3e146105f1575f5ffd5b8063bac7b49714610510578063be46ee9c14610524578063c0a355b21461055c578063c655e95714610565578063c87b56dd14610578575f5ffd5b80638da5cb5b116100fa5780638da5cb5b1461049357806395d89b41146104a6578063a22cb465146104ae578063ad84f341146104c1578063b88d4fde146104fd575f5ffd5b80637ccd0315146104145780638456cb5914610427578063855670ae1461042f578063866b0138146104615780638937214814610480575f5ffd5b80633ce86c62116101c157806355f804b31161018657806355f804b3146103c05780636352211e146103d35780636c0360eb146103e65780636c3fda1d146103ee57806370a0823114610401575f5ffd5b80633ce86c621461036d5780633f4ba83a14610380578063405ce5891461038857806342842e0e1461039a578063452a9320146103ad575f5ffd5b80631c761167116102075780631c761167146102f757806323b872dd1461030a57806325ca4c9c1461031d5780632fcb4f041461034757806334d4e4a51461035a575f5ffd5b806301ffc9a71461024357806306fdde031461026b578063081812fc14610280578063095ea7b3146102c057806313c50f78146102d5575b5f5ffd5b61025661025136600461216f565b610613565b60405190151581526020015b60405180910390f35b610273610664565b60405161026291906121bf565b6102a861028e3660046121d1565b60046020525f90815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610262565b6102d36102ce3660046121fc565b6106ef565b005b6102566102e33660046121d1565b600b6020525f908152604090205460ff1681565b6102a8610305366004612239565b6107d3565b6102d3610318366004612275565b610864565b61025661032b3660046122a2565b6001600160a01b03165f908152600c6020526040902054151590565b6102d36103553660046122a2565b610923565b6102a86103683660046122bd565b610998565b6102d361037b3660046122fa565b610bd1565b6102d3610dca565b600a545b604051908152602001610262565b6102d36103a8366004612275565b610de3565b6007546102a8906001600160a01b031681565b6102d36103ce3660046123c7565b610e9c565b6102a86103e13660046121d1565b610ed8565b610273610f2e565b6102a86103fc3660046121d1565b610f3b565b61038c61040f3660046122a2565b610f63565b6102d36104223660046122a2565b610fc4565b6102d36111ab565b60075461044990600160a81b90046001600160581b031681565b6040516001600160581b039091168152602001610262565b61038c61046f3660046122a2565b600c6020525f908152604090205481565b6102d361048e3660046121d1565b61121f565b6006546102a8906001600160a01b031681565b6102736112de565b6102d36104bc366004612415565b6112eb565b6006546104e090600160a01b90046bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610262565b6102d361050b366004612448565b611356565b60075461025690600160a01b900460ff1681565b6102a86105323660046122a2565b6001600160a01b039081165f908152600c6020908152604080832054835260029091529020541690565b61038c60095481565b6102d3610573366004612448565b611419565b6102736105863660046121d1565b61177d565b6102566105993660046124b6565b600560209081525f928352604080842090915290825290205460ff1681565b6102d36105c63660046122a2565b6117d9565b6102d36105d93660046124ed565b61184e565b6102d36105ec36600461252a565b611922565b6106046105ff3660046121d1565b6119ab565b60405161026293929190612543565b5f6301ffc9a760e01b6001600160e01b03198316148061064357506380ac58cd60e01b6001600160e01b03198316145b8061065e5750635b5e139f60e01b6001600160e01b03198316145b92915050565b5f80546106709061256e565b80601f016020809104026020016040519081016040528092919081815260200182805461069c9061256e565b80156106e75780601f106106be576101008083540402835291602001916106e7565b820191905f5260205f20905b8154815290600101906020018083116106ca57829003601f168201915b505050505081565b5f818152600260205260409020546001600160a01b03163381148061073657506001600160a01b0381165f90815260056020908152604080832033845290915290205460ff165b6107785760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b5f8281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b5f81156107e057816107f4565b600754600160a81b90046001600160581b03165b6040516001600160e01b031960e086811b8216602084015287901b1660248201529092505f9060280160408051601f1981840301815291815281516020928301205f868152600d90935291206001015490915061085b9082906001600160a01b0316611a60565b95945050505050565b5f600a6108726001846125ba565b81548110610882576108826125cd565b5f918252602090912001546001600160a01b03908116915083168190036108bc57604051634e46966960e11b815260040160405180910390fd5b60405163f2fde38b60e01b81526001600160a01b03848116600483015282169063f2fde38b906024015f604051808303815f87803b1580156108fc575f5ffd5b505af115801561090e573d5f5f3e3d5ffd5b5050505061091d848484611afe565b50505050565b6006546001600160a01b0316331461094d5760405162461bcd60e51b815260040161076f906125e1565b600780546001600160a01b0319166001600160a01b03831690811790915560405133907fa14fc14d8620a708a896fd11392a235647d99385500a295f0d7da2a258b2e967905f90a350565b6007545f90600160a01b900460ff16156109c55760405163bbc5234f60e01b815260040160405180910390fd5b82156109d157826109e5565b600754600160a81b90046001600160581b03165b600754909350600160a81b90046001600160581b0316831115610a1b5760405163a93eca7960e01b815260040160405180910390fd5b5f838152600b602052604090205460ff1615610a4a5760405163125b49b360e31b815260040160405180910390fd5b6040516001600160e01b031960e086811b8216602084015232901b1660248201525f9060280160408051601f1981840301815291815281516020928301205f878152600d909352912060010154909150610aae9082906001600160a01b0316611cc0565b600a80546001810182557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80180546001600160a01b0319166001600160a01b03841690811790915590545f918252600c6020526040909120819055909250610b17903390611d3d565b5f848152600d60205260409081902054905163c0c53b8b60e01b81523360048201526001600160a01b03918216602482015284821660448201529083169063c0c53b8b906064015f604051808303815f87803b158015610b75575f5ffd5b505af1158015610b87573d5f5f3e3d5ffd5b50506040516001600160581b03871692506001600160a01b03851691507fb942724c61c2812433bb6ffa28d5bcc8563c9a7edee4473d04ee8fed8e6e9de3905f90a3509392505050565b6001600160a01b038481165f908152600c602090815260408083205483526002909152902054163314610c17576040516312272fd360e11b815260040160405180910390fd5b5f838152600b602052604090205460ff1615610c465760405163125b49b360e31b815260040160405180910390fd5b5f846001600160a01b031663bc68c6766040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c83573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ca79190612607565b90505f610ce984846009548589604051602001610cce929190918252602082015260400190565b60405160208183030381529060405280519060200120611e46565b905080610d095760405163012fa17760e61b815260040160405180910390fd5b5f858152600d602052604090819020600181015481549251632c3c717360e01b81526001600160a01b038a811694632c3c717394610d579483169392909116918b916002019060040161261e565b5f604051808303815f87803b158015610d6e575f5ffd5b505af1158015610d80573d5f5f3e3d5ffd5b50506040516001600160581b03881692506001600160a01b03891691507fb942724c61c2812433bb6ffa28d5bcc8563c9a7edee4473d04ee8fed8e6e9de3905f90a3505050505050565b60405163ced4f63360e01b815260040160405180910390fd5b5f600a610df16001846125ba565b81548110610e0157610e016125cd565b5f918252602090912001546001600160a01b0390811691508316819003610e3b57604051634e46966960e11b815260040160405180910390fd5b60405163f2fde38b60e01b81526001600160a01b03848116600483015282169063f2fde38b906024015f604051808303815f87803b158015610e7b575f5ffd5b505af1158015610e8d573d5f5f3e3d5ffd5b5050505061091d848484611e7e565b6006546001600160a01b03163314610ec65760405162461bcd60e51b815260040161076f906125e1565b6008610ed3828483612720565b505050565b5f818152600260205260409020546001600160a01b031680610f295760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b604482015260640161076f565b919050565b600880546106709061256e565b600a8181548110610f4a575f80fd5b5f918252602090912001546001600160a01b0316905081565b5f6001600160a01b038216610fa95760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b604482015260640161076f565b506001600160a01b03165f9081526003602052604090205490565b6001600160a01b038116610feb57604051634e46966960e11b815260040160405180910390fd5b336001600160a01b0382160361101457604051634e46966960e11b815260040160405180910390fd5b335f908152600c6020526040812054908190036110445760405163f3f6425d60e01b815260040160405180910390fd5b5f81815260026020908152604080832080546001600160a01b039081168086526003855283862080545f190190559087168086528386208054600101905586865282546001600160a01b0319908116821790935560049094529190932080549093169092553b158015906111475750604051630a85bd0160e11b8082523360048301526001600160a01b03838116602484015260448301859052608060648401525f608484015290919085169063150b7a029060a4016020604051808303815f875af1158015611116573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061113a91906127da565b6001600160e01b03191614155b1561116557604051633da6393160e01b815260040160405180910390fd5b81836001600160a01b0316826001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6007546001600160a01b031633146111d657604051636570ecab60e11b815260040160405180910390fd5b6007805460ff60a01b1916600160a01b179055604051600181527f549bab54c75a364ce0e438a4fbf09df7e6b096bcc83a6f91065a0fc8e410b29a9060200160405180910390a1565b6006546001600160a01b031633146112495760405162461bcd60e51b815260040161076f906125e1565b8015806112675750600754600160a81b90046001600160581b031681115b156112855760405163a93eca7960e01b815260040160405180910390fd5b5f818152600b6020908152604091829020805460ff1916600117905590516001600160581b03831681527feeb2feae0739ceec246b003c004c3f0d01c1fea822b7f668ac59e7de193ee7e191015b60405180910390a150565b600180546106709061256e565b335f8181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b5f600a6113646001866125ba565b81548110611374576113746125cd565b5f918252602090912001546001600160a01b03908116915085168190036113ae57604051634e46966960e11b815260040160405180910390fd5b60405163f2fde38b60e01b81526001600160a01b03868116600483015282169063f2fde38b906024015f604051808303815f87803b1580156113ee575f5ffd5b505af1158015611400573d5f5f3e3d5ffd5b505050506114118686868686611f6d565b505050505050565b6006546001600160a01b031633146114435760405162461bcd60e51b815260040161076f906125e1565b826114615760405163152794b760e31b815260040160405180910390fd5b6001600160a01b038416611488576040516316409b0760e01b815260040160405180910390fd5b600780546001600160a81b038116600160a81b918290046001600160581b0390811660010116918202179091556009849055604080516060810182526001600160a01b03888116825287166020808301919091528251601f8601829004820281018201845285815291928301919086908690819084018382808284375f920182905250939094525050838152600d6020908152604091829020845181546001600160a01b03199081166001600160a01b039283161783559286015160018301805490941691161790915590830151909150600282019061156890826127f5565b50905050600760159054906101000a90046001600160581b03166001600160581b0316856001600160a01b031663bc68c6766040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115c7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115eb9190612607565b146116095760405163714f551360e01b815260040160405180910390fd5b306001600160a01b0316856001600160a01b0316632dd310006040518163ffffffff1660e01b8152600401602060405180830381865afa15801561164f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061167391906128b0565b6001600160a01b03161461169a57604051630539b97b60e21b815260040160405180910390fd5b306001600160a01b0316866001600160a01b0316632dd310006040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116e0573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061170491906128b0565b6001600160a01b03161461172b57604051630539b97b60e21b815260040160405180910390fd5b846001600160a01b0316866001600160a01b0316826001600160581b03167f7a76ee3d6c40ab211805bcb8ef8f41f0c86929a436491a2520b78930f580202e60405160405180910390a4505050505050565b60605f6008805461178d9061256e565b9050116117a85760405180602001604052805f81525061065e565b60086117b383612052565b6040516020016117c49291906128e2565b60405160208183030381529060405292915050565b6006546001600160a01b031633146118035760405162461bcd60e51b815260040161076f906125e1565b600680546001600160a01b0319166001600160a01b03831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a350565b806001600160a01b0316826001600160a01b03160361188057604051634e46966960e11b815260040160405180910390fd5b6001600160a01b0381165f908152600c6020526040902054600a6118a56001836125ba565b815481106118b5576118b56125cd565b5f9182526020909120015460405163f2fde38b60e01b81526001600160a01b0385811660048301529091169063f2fde38b906024015f604051808303815f87803b158015611901575f5ffd5b505af1158015611913573d5f5f3e3d5ffd5b5050505061091d848483611e7e565b6006546001600160a01b0316331461194c5760405162461bcd60e51b815260040161076f906125e1565b6007547f549bab54c75a364ce0e438a4fbf09df7e6b096bcc83a6f91065a0fc8e410b29a90600160a01b900460ff1680156119845750815b6007805460ff60a01b1916600160a01b9215159283021790556040519081526020016112d3565b600d6020525f90815260409020805460018201546002830180546001600160a01b039384169492909316926119df9061256e565b80601f0160208091040260200160405190810160405280929190818152602001828054611a0b9061256e565b8015611a565780601f10611a2d57610100808354040283529160200191611a56565b820191905f5260205f20905b815481529060010190602001808311611a3957829003601f168201915b5050505050905083565b5f5f604051806101c001604052806101888152602001612a37610188913983604051602001611a90929190612955565b60408051808303601f1901815282825280516020918201206001600160f81b0319828501523060601b6bffffffffffffffffffffffff191660218501526035840197909752605580840197909752815180840390970187526075909201905284519401939093209392505050565b5f818152600260205260409020546001600160a01b03848116911614611b535760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b604482015260640161076f565b6001600160a01b038216611b9d5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b604482015260640161076f565b336001600160a01b0384161480611bd657506001600160a01b0383165f90815260056020908152604080832033845290915290205460ff165b80611bf657505f818152600460205260409020546001600160a01b031633145b611c335760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161076f565b6001600160a01b038084165f81815260036020908152604080832080545f19019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b5f5f604051806101c001604052806101888152602001612a37610188913983604051602001611cf0929190612955565b6040516020818303038152906040529050838151602083015ff59150816001600160a01b03163b5f03611d36576040516335279f5d60e21b815260040160405180910390fd5b5092915050565b6001600160a01b038216611d875760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b604482015260640161076f565b5f818152600260205260409020546001600160a01b031615611ddc5760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b604482015260640161076f565b6001600160a01b0382165f81815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b5f8315611e76578360051b8501855b803580851160051b94855260209485185260405f209301818110611e555750505b501492915050565b611e89838383610864565b6001600160a01b0382163b1580611f2e5750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401525f608484015290919084169063150b7a029060a4016020604051808303815f875af1158015611efe573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f2291906127da565b6001600160e01b031916145b610ed35760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b604482015260640161076f565b611f78858585610864565b6001600160a01b0384163b158061200c5750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290611fc09033908a90899089908990600401612981565b6020604051808303815f875af1158015611fdc573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061200091906127da565b6001600160e01b031916145b61204b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b604482015260640161076f565b5050505050565b6060815f036120785750506040805180820190915260018152600360fc1b602082015290565b815f5b81156120a1578061208b816129d1565b915061209a9050600a836129fd565b915061207b565b5f8167ffffffffffffffff8111156120bb576120bb6126c8565b6040519080825280601f01601f1916602001820160405280156120e5576020820181803683370190505b5090505b841561214f576120fa6001836125ba565b9150612107600a86612a10565b612112906030612a23565b60f81b818381518110612127576121276125cd565b60200101906001600160f81b03191690815f1a905350612148600a866129fd565b94506120e9565b949350505050565b6001600160e01b03198116811461216c575f5ffd5b50565b5f6020828403121561217f575f5ffd5b813561218a81612157565b9392505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61218a6020830184612191565b5f602082840312156121e1575f5ffd5b5035919050565b6001600160a01b038116811461216c575f5ffd5b5f5f6040838503121561220d575f5ffd5b8235612218816121e8565b946020939093013593505050565b803563ffffffff81168114610f29575f5ffd5b5f5f5f6060848603121561224b575f5ffd5b8335612256816121e8565b925061226460208501612226565b929592945050506040919091013590565b5f5f5f60608486031215612287575f5ffd5b8335612292816121e8565b92506020840135612264816121e8565b5f602082840312156122b2575f5ffd5b813561218a816121e8565b5f5f5f606084860312156122cf575f5ffd5b6122d884612226565b92506020840135915060408401356122ef816121e8565b809150509250925092565b5f5f5f5f6060858703121561230d575f5ffd5b8435612318816121e8565b935060208501359250604085013567ffffffffffffffff81111561233a575f5ffd5b8501601f8101871361234a575f5ffd5b803567ffffffffffffffff811115612360575f5ffd5b8760208260051b8401011115612374575f5ffd5b949793965060200194505050565b5f5f83601f840112612392575f5ffd5b50813567ffffffffffffffff8111156123a9575f5ffd5b6020830191508360208285010111156123c0575f5ffd5b9250929050565b5f5f602083850312156123d8575f5ffd5b823567ffffffffffffffff8111156123ee575f5ffd5b6123fa85828601612382565b90969095509350505050565b80358015158114610f29575f5ffd5b5f5f60408385031215612426575f5ffd5b8235612431816121e8565b915061243f60208401612406565b90509250929050565b5f5f5f5f5f6080868803121561245c575f5ffd5b8535612467816121e8565b94506020860135612477816121e8565b935060408601359250606086013567ffffffffffffffff811115612499575f5ffd5b6124a588828901612382565b969995985093965092949392505050565b5f5f604083850312156124c7575f5ffd5b82356124d2816121e8565b915060208301356124e2816121e8565b809150509250929050565b5f5f5f606084860312156124ff575f5ffd5b833561250a816121e8565b9250602084013561251a816121e8565b915060408401356122ef816121e8565b5f6020828403121561253a575f5ffd5b61218a82612406565b6001600160a01b038481168252831660208201526060604082018190525f9061085b90830184612191565b600181811c9082168061258257607f821691505b6020821081036125a057634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561065e5761065e6125a6565b634e487b7160e01b5f52603260045260245ffd5b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b5f60208284031215612617575f5ffd5b5051919050565b6001600160a01b03858116825284166020820152604081018390526080606082015281545f90819061264f8161256e565b806080860152600182165f811461266d5760018114612689576126ba565b60ff19831660a087015260a082151560051b87010193506126ba565b865f5260205f205f5b838110156126b157815488820160a00152600190910190602001612692565b870160a0019450505b509198975050505050505050565b634e487b7160e01b5f52604160045260245ffd5b601f821115610ed357805f5260205f20601f840160051c810160208510156127015750805b601f840160051c820191505b8181101561204b575f815560010161270d565b67ffffffffffffffff831115612738576127386126c8565b61274c83612746835461256e565b836126dc565b5f601f84116001811461277d575f85156127665750838201355b5f19600387901b1c1916600186901b17835561204b565b5f83815260208120601f198716915b828110156127ac578685013582556020948501946001909201910161278c565b50868210156127c8575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f602082840312156127ea575f5ffd5b815161218a81612157565b815167ffffffffffffffff81111561280f5761280f6126c8565b6128238161281d845461256e565b846126dc565b6020601f821160018114612855575f831561283e5750848201515b5f19600385901b1c1916600184901b17845561204b565b5f84815260208120601f198516915b828110156128845787850151825560209485019460019092019101612864565b50848210156128a157868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f602082840312156128c0575f5ffd5b815161218a816121e8565b5f81518060208401855e5f93019283525090919050565b5f5f84546128ef8161256e565b600182168015612906576001811461291b57612948565b60ff1983168652811515820286019350612948565b875f5260205f205f5b8381101561294057815488820152600190910190602001612924565b505081860193505b50505061085b81856128cb565b5f61296082856128cb565b60609390931b6bffffffffffffffffffffffff191683525050601401919050565b6001600160a01b03868116825285166020820152604081018490526080606082018190528101829052818360a08301375f81830160a090810191909152601f909201601f19160101949350505050565b5f600182016129e2576129e26125a6565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f82612a0b57612a0b6129e9565b500490565b5f82612a1e57612a1e6129e9565b500690565b8082018082111561065e5761065e6125a656fe608060405260405161017c38038061017c8339810160408190526100229161008d565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0383169081179091556040517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2506100ba565b5f6020828403121561009d575f80fd5b81516001600160a01b03811681146100b3575f80fd5b9392505050565b60b6806100c65f395ff3fe608060405236603c57603a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b546001600160a01b03166063565b005b603a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc602c565b365f80375f80365f845af43d5f803e808015607c573d5ff35b3d5ffdfea2646970667358221220eeb8a2fa918a2057b66e1d3fa3930647dc7a4e56c99898cd9e280beec9d9ba9f64736f6c63430008160033000000000000000000000000a2646970667358221220e692782929f11016cc84da3379971dfe41c1e8a949b77285e545e732f054d9cd64736f6c634300081e0033000000000000000000000000b4d72b1c91e640e4ed7d7397f3244de4d8acc50b

Deployed Bytecode

0x608060405234801561000f575f5ffd5b506004361061023f575f3560e01c80637ccd031511610135578063bac7b497116100b4578063e985e9c511610079578063e985e9c51461058b578063f2fde38b146105b8578063f7ac6490146105cb578063fa807239146105de578063fa907c3e146105f1575f5ffd5b8063bac7b49714610510578063be46ee9c14610524578063c0a355b21461055c578063c655e95714610565578063c87b56dd14610578575f5ffd5b80638da5cb5b116100fa5780638da5cb5b1461049357806395d89b41146104a6578063a22cb465146104ae578063ad84f341146104c1578063b88d4fde146104fd575f5ffd5b80637ccd0315146104145780638456cb5914610427578063855670ae1461042f578063866b0138146104615780638937214814610480575f5ffd5b80633ce86c62116101c157806355f804b31161018657806355f804b3146103c05780636352211e146103d35780636c0360eb146103e65780636c3fda1d146103ee57806370a0823114610401575f5ffd5b80633ce86c621461036d5780633f4ba83a14610380578063405ce5891461038857806342842e0e1461039a578063452a9320146103ad575f5ffd5b80631c761167116102075780631c761167146102f757806323b872dd1461030a57806325ca4c9c1461031d5780632fcb4f041461034757806334d4e4a51461035a575f5ffd5b806301ffc9a71461024357806306fdde031461026b578063081812fc14610280578063095ea7b3146102c057806313c50f78146102d5575b5f5ffd5b61025661025136600461216f565b610613565b60405190151581526020015b60405180910390f35b610273610664565b60405161026291906121bf565b6102a861028e3660046121d1565b60046020525f90815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610262565b6102d36102ce3660046121fc565b6106ef565b005b6102566102e33660046121d1565b600b6020525f908152604090205460ff1681565b6102a8610305366004612239565b6107d3565b6102d3610318366004612275565b610864565b61025661032b3660046122a2565b6001600160a01b03165f908152600c6020526040902054151590565b6102d36103553660046122a2565b610923565b6102a86103683660046122bd565b610998565b6102d361037b3660046122fa565b610bd1565b6102d3610dca565b600a545b604051908152602001610262565b6102d36103a8366004612275565b610de3565b6007546102a8906001600160a01b031681565b6102d36103ce3660046123c7565b610e9c565b6102a86103e13660046121d1565b610ed8565b610273610f2e565b6102a86103fc3660046121d1565b610f3b565b61038c61040f3660046122a2565b610f63565b6102d36104223660046122a2565b610fc4565b6102d36111ab565b60075461044990600160a81b90046001600160581b031681565b6040516001600160581b039091168152602001610262565b61038c61046f3660046122a2565b600c6020525f908152604090205481565b6102d361048e3660046121d1565b61121f565b6006546102a8906001600160a01b031681565b6102736112de565b6102d36104bc366004612415565b6112eb565b6006546104e090600160a01b90046bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff9091168152602001610262565b6102d361050b366004612448565b611356565b60075461025690600160a01b900460ff1681565b6102a86105323660046122a2565b6001600160a01b039081165f908152600c6020908152604080832054835260029091529020541690565b61038c60095481565b6102d3610573366004612448565b611419565b6102736105863660046121d1565b61177d565b6102566105993660046124b6565b600560209081525f928352604080842090915290825290205460ff1681565b6102d36105c63660046122a2565b6117d9565b6102d36105d93660046124ed565b61184e565b6102d36105ec36600461252a565b611922565b6106046105ff3660046121d1565b6119ab565b60405161026293929190612543565b5f6301ffc9a760e01b6001600160e01b03198316148061064357506380ac58cd60e01b6001600160e01b03198316145b8061065e5750635b5e139f60e01b6001600160e01b03198316145b92915050565b5f80546106709061256e565b80601f016020809104026020016040519081016040528092919081815260200182805461069c9061256e565b80156106e75780601f106106be576101008083540402835291602001916106e7565b820191905f5260205f20905b8154815290600101906020018083116106ca57829003601f168201915b505050505081565b5f818152600260205260409020546001600160a01b03163381148061073657506001600160a01b0381165f90815260056020908152604080832033845290915290205460ff165b6107785760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b60448201526064015b60405180910390fd5b5f8281526004602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b5f81156107e057816107f4565b600754600160a81b90046001600160581b03165b6040516001600160e01b031960e086811b8216602084015287901b1660248201529092505f9060280160408051601f1981840301815291815281516020928301205f868152600d90935291206001015490915061085b9082906001600160a01b0316611a60565b95945050505050565b5f600a6108726001846125ba565b81548110610882576108826125cd565b5f918252602090912001546001600160a01b03908116915083168190036108bc57604051634e46966960e11b815260040160405180910390fd5b60405163f2fde38b60e01b81526001600160a01b03848116600483015282169063f2fde38b906024015f604051808303815f87803b1580156108fc575f5ffd5b505af115801561090e573d5f5f3e3d5ffd5b5050505061091d848484611afe565b50505050565b6006546001600160a01b0316331461094d5760405162461bcd60e51b815260040161076f906125e1565b600780546001600160a01b0319166001600160a01b03831690811790915560405133907fa14fc14d8620a708a896fd11392a235647d99385500a295f0d7da2a258b2e967905f90a350565b6007545f90600160a01b900460ff16156109c55760405163bbc5234f60e01b815260040160405180910390fd5b82156109d157826109e5565b600754600160a81b90046001600160581b03165b600754909350600160a81b90046001600160581b0316831115610a1b5760405163a93eca7960e01b815260040160405180910390fd5b5f838152600b602052604090205460ff1615610a4a5760405163125b49b360e31b815260040160405180910390fd5b6040516001600160e01b031960e086811b8216602084015232901b1660248201525f9060280160408051601f1981840301815291815281516020928301205f878152600d909352912060010154909150610aae9082906001600160a01b0316611cc0565b600a80546001810182557fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80180546001600160a01b0319166001600160a01b03841690811790915590545f918252600c6020526040909120819055909250610b17903390611d3d565b5f848152600d60205260409081902054905163c0c53b8b60e01b81523360048201526001600160a01b03918216602482015284821660448201529083169063c0c53b8b906064015f604051808303815f87803b158015610b75575f5ffd5b505af1158015610b87573d5f5f3e3d5ffd5b50506040516001600160581b03871692506001600160a01b03851691507fb942724c61c2812433bb6ffa28d5bcc8563c9a7edee4473d04ee8fed8e6e9de3905f90a3509392505050565b6001600160a01b038481165f908152600c602090815260408083205483526002909152902054163314610c17576040516312272fd360e11b815260040160405180910390fd5b5f838152600b602052604090205460ff1615610c465760405163125b49b360e31b815260040160405180910390fd5b5f846001600160a01b031663bc68c6766040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c83573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ca79190612607565b90505f610ce984846009548589604051602001610cce929190918252602082015260400190565b60405160208183030381529060405280519060200120611e46565b905080610d095760405163012fa17760e61b815260040160405180910390fd5b5f858152600d602052604090819020600181015481549251632c3c717360e01b81526001600160a01b038a811694632c3c717394610d579483169392909116918b916002019060040161261e565b5f604051808303815f87803b158015610d6e575f5ffd5b505af1158015610d80573d5f5f3e3d5ffd5b50506040516001600160581b03881692506001600160a01b03891691507fb942724c61c2812433bb6ffa28d5bcc8563c9a7edee4473d04ee8fed8e6e9de3905f90a3505050505050565b60405163ced4f63360e01b815260040160405180910390fd5b5f600a610df16001846125ba565b81548110610e0157610e016125cd565b5f918252602090912001546001600160a01b0390811691508316819003610e3b57604051634e46966960e11b815260040160405180910390fd5b60405163f2fde38b60e01b81526001600160a01b03848116600483015282169063f2fde38b906024015f604051808303815f87803b158015610e7b575f5ffd5b505af1158015610e8d573d5f5f3e3d5ffd5b5050505061091d848484611e7e565b6006546001600160a01b03163314610ec65760405162461bcd60e51b815260040161076f906125e1565b6008610ed3828483612720565b505050565b5f818152600260205260409020546001600160a01b031680610f295760405162461bcd60e51b815260206004820152600a6024820152691393d517d3525395115160b21b604482015260640161076f565b919050565b600880546106709061256e565b600a8181548110610f4a575f80fd5b5f918252602090912001546001600160a01b0316905081565b5f6001600160a01b038216610fa95760405162461bcd60e51b815260206004820152600c60248201526b5a45524f5f4144445245535360a01b604482015260640161076f565b506001600160a01b03165f9081526003602052604090205490565b6001600160a01b038116610feb57604051634e46966960e11b815260040160405180910390fd5b336001600160a01b0382160361101457604051634e46966960e11b815260040160405180910390fd5b335f908152600c6020526040812054908190036110445760405163f3f6425d60e01b815260040160405180910390fd5b5f81815260026020908152604080832080546001600160a01b039081168086526003855283862080545f190190559087168086528386208054600101905586865282546001600160a01b0319908116821790935560049094529190932080549093169092553b158015906111475750604051630a85bd0160e11b8082523360048301526001600160a01b03838116602484015260448301859052608060648401525f608484015290919085169063150b7a029060a4016020604051808303815f875af1158015611116573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061113a91906127da565b6001600160e01b03191614155b1561116557604051633da6393160e01b815260040160405180910390fd5b81836001600160a01b0316826001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6007546001600160a01b031633146111d657604051636570ecab60e11b815260040160405180910390fd5b6007805460ff60a01b1916600160a01b179055604051600181527f549bab54c75a364ce0e438a4fbf09df7e6b096bcc83a6f91065a0fc8e410b29a9060200160405180910390a1565b6006546001600160a01b031633146112495760405162461bcd60e51b815260040161076f906125e1565b8015806112675750600754600160a81b90046001600160581b031681115b156112855760405163a93eca7960e01b815260040160405180910390fd5b5f818152600b6020908152604091829020805460ff1916600117905590516001600160581b03831681527feeb2feae0739ceec246b003c004c3f0d01c1fea822b7f668ac59e7de193ee7e191015b60405180910390a150565b600180546106709061256e565b335f8181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b5f600a6113646001866125ba565b81548110611374576113746125cd565b5f918252602090912001546001600160a01b03908116915085168190036113ae57604051634e46966960e11b815260040160405180910390fd5b60405163f2fde38b60e01b81526001600160a01b03868116600483015282169063f2fde38b906024015f604051808303815f87803b1580156113ee575f5ffd5b505af1158015611400573d5f5f3e3d5ffd5b505050506114118686868686611f6d565b505050505050565b6006546001600160a01b031633146114435760405162461bcd60e51b815260040161076f906125e1565b826114615760405163152794b760e31b815260040160405180910390fd5b6001600160a01b038416611488576040516316409b0760e01b815260040160405180910390fd5b600780546001600160a81b038116600160a81b918290046001600160581b0390811660010116918202179091556009849055604080516060810182526001600160a01b03888116825287166020808301919091528251601f8601829004820281018201845285815291928301919086908690819084018382808284375f920182905250939094525050838152600d6020908152604091829020845181546001600160a01b03199081166001600160a01b039283161783559286015160018301805490941691161790915590830151909150600282019061156890826127f5565b50905050600760159054906101000a90046001600160581b03166001600160581b0316856001600160a01b031663bc68c6766040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115c7573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115eb9190612607565b146116095760405163714f551360e01b815260040160405180910390fd5b306001600160a01b0316856001600160a01b0316632dd310006040518163ffffffff1660e01b8152600401602060405180830381865afa15801561164f573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061167391906128b0565b6001600160a01b03161461169a57604051630539b97b60e21b815260040160405180910390fd5b306001600160a01b0316866001600160a01b0316632dd310006040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116e0573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061170491906128b0565b6001600160a01b03161461172b57604051630539b97b60e21b815260040160405180910390fd5b846001600160a01b0316866001600160a01b0316826001600160581b03167f7a76ee3d6c40ab211805bcb8ef8f41f0c86929a436491a2520b78930f580202e60405160405180910390a4505050505050565b60605f6008805461178d9061256e565b9050116117a85760405180602001604052805f81525061065e565b60086117b383612052565b6040516020016117c49291906128e2565b60405160208183030381529060405292915050565b6006546001600160a01b031633146118035760405162461bcd60e51b815260040161076f906125e1565b600680546001600160a01b0319166001600160a01b03831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a350565b806001600160a01b0316826001600160a01b03160361188057604051634e46966960e11b815260040160405180910390fd5b6001600160a01b0381165f908152600c6020526040902054600a6118a56001836125ba565b815481106118b5576118b56125cd565b5f9182526020909120015460405163f2fde38b60e01b81526001600160a01b0385811660048301529091169063f2fde38b906024015f604051808303815f87803b158015611901575f5ffd5b505af1158015611913573d5f5f3e3d5ffd5b5050505061091d848483611e7e565b6006546001600160a01b0316331461194c5760405162461bcd60e51b815260040161076f906125e1565b6007547f549bab54c75a364ce0e438a4fbf09df7e6b096bcc83a6f91065a0fc8e410b29a90600160a01b900460ff1680156119845750815b6007805460ff60a01b1916600160a01b9215159283021790556040519081526020016112d3565b600d6020525f90815260409020805460018201546002830180546001600160a01b039384169492909316926119df9061256e565b80601f0160208091040260200160405190810160405280929190818152602001828054611a0b9061256e565b8015611a565780601f10611a2d57610100808354040283529160200191611a56565b820191905f5260205f20905b815481529060010190602001808311611a3957829003601f168201915b5050505050905083565b5f5f604051806101c001604052806101888152602001612a37610188913983604051602001611a90929190612955565b60408051808303601f1901815282825280516020918201206001600160f81b0319828501523060601b6bffffffffffffffffffffffff191660218501526035840197909752605580840197909752815180840390970187526075909201905284519401939093209392505050565b5f818152600260205260409020546001600160a01b03848116911614611b535760405162461bcd60e51b815260206004820152600a60248201526957524f4e475f46524f4d60b01b604482015260640161076f565b6001600160a01b038216611b9d5760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b604482015260640161076f565b336001600160a01b0384161480611bd657506001600160a01b0383165f90815260056020908152604080832033845290915290205460ff165b80611bf657505f818152600460205260409020546001600160a01b031633145b611c335760405162461bcd60e51b815260206004820152600e60248201526d1393d517d055551213d49256915160921b604482015260640161076f565b6001600160a01b038084165f81815260036020908152604080832080545f19019055938616808352848320805460010190558583526002825284832080546001600160a01b03199081168317909155600490925284832080549092169091559251849392917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b5f5f604051806101c001604052806101888152602001612a37610188913983604051602001611cf0929190612955565b6040516020818303038152906040529050838151602083015ff59150816001600160a01b03163b5f03611d36576040516335279f5d60e21b815260040160405180910390fd5b5092915050565b6001600160a01b038216611d875760405162461bcd60e51b81526020600482015260116024820152701253959053125117d49150d25412515395607a1b604482015260640161076f565b5f818152600260205260409020546001600160a01b031615611ddc5760405162461bcd60e51b815260206004820152600e60248201526d1053149150511657d3525395115160921b604482015260640161076f565b6001600160a01b0382165f81815260036020908152604080832080546001019055848352600290915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b5f8315611e76578360051b8501855b803580851160051b94855260209485185260405f209301818110611e555750505b501492915050565b611e89838383610864565b6001600160a01b0382163b1580611f2e5750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401525f608484015290919084169063150b7a029060a4016020604051808303815f875af1158015611efe573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f2291906127da565b6001600160e01b031916145b610ed35760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b604482015260640161076f565b611f78858585610864565b6001600160a01b0384163b158061200c5750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a0290611fc09033908a90899089908990600401612981565b6020604051808303815f875af1158015611fdc573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061200091906127da565b6001600160e01b031916145b61204b5760405162461bcd60e51b815260206004820152601060248201526f155394d0519157d49150d2541251539560821b604482015260640161076f565b5050505050565b6060815f036120785750506040805180820190915260018152600360fc1b602082015290565b815f5b81156120a1578061208b816129d1565b915061209a9050600a836129fd565b915061207b565b5f8167ffffffffffffffff8111156120bb576120bb6126c8565b6040519080825280601f01601f1916602001820160405280156120e5576020820181803683370190505b5090505b841561214f576120fa6001836125ba565b9150612107600a86612a10565b612112906030612a23565b60f81b818381518110612127576121276125cd565b60200101906001600160f81b03191690815f1a905350612148600a866129fd565b94506120e9565b949350505050565b6001600160e01b03198116811461216c575f5ffd5b50565b5f6020828403121561217f575f5ffd5b813561218a81612157565b9392505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61218a6020830184612191565b5f602082840312156121e1575f5ffd5b5035919050565b6001600160a01b038116811461216c575f5ffd5b5f5f6040838503121561220d575f5ffd5b8235612218816121e8565b946020939093013593505050565b803563ffffffff81168114610f29575f5ffd5b5f5f5f6060848603121561224b575f5ffd5b8335612256816121e8565b925061226460208501612226565b929592945050506040919091013590565b5f5f5f60608486031215612287575f5ffd5b8335612292816121e8565b92506020840135612264816121e8565b5f602082840312156122b2575f5ffd5b813561218a816121e8565b5f5f5f606084860312156122cf575f5ffd5b6122d884612226565b92506020840135915060408401356122ef816121e8565b809150509250925092565b5f5f5f5f6060858703121561230d575f5ffd5b8435612318816121e8565b935060208501359250604085013567ffffffffffffffff81111561233a575f5ffd5b8501601f8101871361234a575f5ffd5b803567ffffffffffffffff811115612360575f5ffd5b8760208260051b8401011115612374575f5ffd5b949793965060200194505050565b5f5f83601f840112612392575f5ffd5b50813567ffffffffffffffff8111156123a9575f5ffd5b6020830191508360208285010111156123c0575f5ffd5b9250929050565b5f5f602083850312156123d8575f5ffd5b823567ffffffffffffffff8111156123ee575f5ffd5b6123fa85828601612382565b90969095509350505050565b80358015158114610f29575f5ffd5b5f5f60408385031215612426575f5ffd5b8235612431816121e8565b915061243f60208401612406565b90509250929050565b5f5f5f5f5f6080868803121561245c575f5ffd5b8535612467816121e8565b94506020860135612477816121e8565b935060408601359250606086013567ffffffffffffffff811115612499575f5ffd5b6124a588828901612382565b969995985093965092949392505050565b5f5f604083850312156124c7575f5ffd5b82356124d2816121e8565b915060208301356124e2816121e8565b809150509250929050565b5f5f5f606084860312156124ff575f5ffd5b833561250a816121e8565b9250602084013561251a816121e8565b915060408401356122ef816121e8565b5f6020828403121561253a575f5ffd5b61218a82612406565b6001600160a01b038481168252831660208201526060604082018190525f9061085b90830184612191565b600181811c9082168061258257607f821691505b6020821081036125a057634e487b7160e01b5f52602260045260245ffd5b50919050565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561065e5761065e6125a6565b634e487b7160e01b5f52603260045260245ffd5b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b5f60208284031215612617575f5ffd5b5051919050565b6001600160a01b03858116825284166020820152604081018390526080606082015281545f90819061264f8161256e565b806080860152600182165f811461266d5760018114612689576126ba565b60ff19831660a087015260a082151560051b87010193506126ba565b865f5260205f205f5b838110156126b157815488820160a00152600190910190602001612692565b870160a0019450505b509198975050505050505050565b634e487b7160e01b5f52604160045260245ffd5b601f821115610ed357805f5260205f20601f840160051c810160208510156127015750805b601f840160051c820191505b8181101561204b575f815560010161270d565b67ffffffffffffffff831115612738576127386126c8565b61274c83612746835461256e565b836126dc565b5f601f84116001811461277d575f85156127665750838201355b5f19600387901b1c1916600186901b17835561204b565b5f83815260208120601f198716915b828110156127ac578685013582556020948501946001909201910161278c565b50868210156127c8575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f602082840312156127ea575f5ffd5b815161218a81612157565b815167ffffffffffffffff81111561280f5761280f6126c8565b6128238161281d845461256e565b846126dc565b6020601f821160018114612855575f831561283e5750848201515b5f19600385901b1c1916600184901b17845561204b565b5f84815260208120601f198516915b828110156128845787850151825560209485019460019092019101612864565b50848210156128a157868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b5f602082840312156128c0575f5ffd5b815161218a816121e8565b5f81518060208401855e5f93019283525090919050565b5f5f84546128ef8161256e565b600182168015612906576001811461291b57612948565b60ff1983168652811515820286019350612948565b875f5260205f205f5b8381101561294057815488820152600190910190602001612924565b505081860193505b50505061085b81856128cb565b5f61296082856128cb565b60609390931b6bffffffffffffffffffffffff191683525050601401919050565b6001600160a01b03868116825285166020820152604081018490526080606082018190528101829052818360a08301375f81830160a090810191909152601f909201601f19160101949350505050565b5f600182016129e2576129e26125a6565b5060010190565b634e487b7160e01b5f52601260045260245ffd5b5f82612a0b57612a0b6129e9565b500490565b5f82612a1e57612a1e6129e9565b500690565b8082018082111561065e5761065e6125a656fe608060405260405161017c38038061017c8339810160408190526100229161008d565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b0319166001600160a01b0383169081179091556040517fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b905f90a2506100ba565b5f6020828403121561009d575f80fd5b81516001600160a01b03811681146100b3575f80fd5b9392505050565b60b6806100c65f395ff3fe608060405236603c57603a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5b546001600160a01b03166063565b005b603a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc602c565b365f80375f80365f845af43d5f803e808015607c573d5ff35b3d5ffdfea2646970667358221220eeb8a2fa918a2057b66e1d3fa3930647dc7a4e56c99898cd9e280beec9d9ba9f64736f6c63430008160033000000000000000000000000a2646970667358221220e692782929f11016cc84da3379971dfe41c1e8a949b77285e545e732f054d9cd64736f6c634300081e0033

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

000000000000000000000000b4d72b1c91e640e4ed7d7397f3244de4d8acc50b

-----Decoded View---------------
Arg [0] : owner_ (address): 0xb4d72B1c91e640e4ED7d7397F3244De4D8ACc50B

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000b4d72b1c91e640e4ed7d7397f3244de4d8acc50b


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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