ETH Price: $2,914.67 (-0.86%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Amount:Between 1-10
Reset Filter

Transaction Hash
Method
Block
From
To

There are no matching entries

Update your filters to view other transactions

Amount:Between 1-10
Reset Filter

Advanced mode:
Parent Transaction Hash Method Block
From
To

There are no matching entries

Update your filters to view other transactions

View All Internal Transactions
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

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

Contract Source Code Verified (Exact Match)

Contract Name:
Controller

Compiler Version
v0.8.30+commit.73712a01

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion
// SPDX-License-Identifier: UNLICENSED
// Copyright 2025 US Fintech LLC, a New York company.
// 
// Permission to use, copy, modify, or distribute this software is strictly prohibited
// without prior written consent from US Fintech LLC.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL US FINTECH LLC BE LIABLE FOR ANY
// CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE,
// ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// 
// OFFICIAL US FINTECH LLC COMPONENT
// EquityMint Sovereign Model Token Contract System Component
// The Foremost De-Facto Architectural Standard for Real-World Asset (RWA), 
// Fund and ETF-Like Tokenization and Monetization.
// 
// Controller - Central authorization and entity management contract that coordinates all platform operations,
// manages official entities (Super, TreasuryAdmin, SmartContracts), and maintains hierarchical access control
// across the entire EquityMint ecosystem. Complete Asset Management System for all assets including real estate, 
// stocks, bonds, and any monetizable property.
// 
// Chief Architect and CEO: Ken Silverman, US Fintech LLC
// Designed by Ken Silverman as part of the ExecutivePeerTreasury, Controller and IssueToken model.
// @author Ken Silverman
// 
// ⚖️  AUTHORIZED USE RESTRICTIONS:
// Only projects deploying these contracts via the EquityMint platform at equitymint.org 
// which contain this preamble and Fee structures generated through EquityMint.org have 
// permission to use these contracts or any derivative works thereto. Any such deployment 
// must contain these words. This contract is part of a greater system. They are owned 
// and licensed exclusively in writing and through US Fintech, LLC. 
// 
// Any breach of these terms will be investigated and pursued through all available civil 
// and criminal remedies to the fullest extent permitted by applicable law. Enforcement is 
// discretionary. The failure to enforce any provision shall not constitute a waiver of the 
// right to enforce at any time. All projects and platform users interacting with this system 
// are subject to additional terms and conditions as may be published or updated from time to 
// time at https://equitymint.org and/or https://DataCloudOS.com.
pragma solidity 0.8.30;
import "./Recoverable.sol";

interface IERC20SymbolAndName {
        function symbol() external view returns (string memory);
        function name() external view returns (string memory);
}

/// @title Controller
/// @author Ken Silverman
/// @notice This contract is used to manage the official entities of all smart contract in the network.
contract Controller is Recoverable {
    
    uint16 public constant CONTRACT_VERSION = 4305; // Version 4.3.0.5 ensures unique bytecode for verification

 


    
    // Flags are now stored per-fee in parallel feeFlags array: bit0=isPercent, bit1=isTaker

    // Custom errors (saves ~1KB vs require strings)
    error BadAddr();
    error Unauthorized();
    error BadType();
    error ValExceedsMax();
    error EntityLocked();
    error EntityPermLocked();
    error GlobalAddLocked();
    error ParentOff();
    error OnlySuper();
    error OnlyParent();
    error RootAuth();
    error ChildAuthFailed();
    error Need1stTrsy();
    error FstTrsyMustBeRoot();
    error Bad1stTrsry();
    error OnlyPT();
    error NoEntity();
    error EntityNotActive();
    error SelfRemoveOnly();
    error NotParentOrSelf();
    error InvalidEntity();
    error NotAncestor();
    error OnlySuperCanLockRoots();
    error MustWait6Months();
    error GlobalLockAlreadyActive();
    error NotAncestorOrSelf();
    error NeedsSuperEntity();
    error InvalidAdminType();
    error NoValRemove();
    error OnlyPlatformSuperOrSC();
    error OnlyProjectOfficialSC();
    error PlatformAccessAlreadyRevoked();
    error NoPlatformAccess();
    error OnlyPlatformSCOrOpenWindow();

    event UpdateOfficialEnt(
        address indexed entityAddress,
        address indexed updater,
        bytes32 indexed entityTypeHash,  // Hashed admin type (saves ABI encoding cost)
        string action,                   // Add,Remove  (nothing is actually removed, only active boolean changed)
        string fullNameOfEntityOrLabel,  // person's full name or "SC"
        string nationalIdOfEntity,       // registered to entity or SC address if entity is SC
        uint256 blockTimeStamp,          // block number of the event
        bool remainsActive,
        uint256 value  // Associated value (type(uint256).max = NO_VALUE)
    );

    event PlatformAccessPermanentlyRevoked(
        address indexed caller,
        bool byPlatformSuper,
        uint256 timestamp
    );

    // ============================================================
    // 📋 STRUCT DEFINITIONS (Duplicated in IController.sol for external use)
    // ============================================================
    // These structs are the SOURCE OF TRUTH for Controller.sol
    // They are DUPLICATED in IController.sol so other contracts can import
    // the interface without pulling in the full Controller contract.
    // IMPORTANT: Keep both definitions in sync!
    // ============================================================
    
    struct OfficialEntityStruct {
        string fullNameOfEntityOrLabel;
        string nationalIdOfEntity; // (if entity is a smart contract, leave empty or provide some other detail here.)
        address pubAddress;   // registered to entity or SC address if entity is SC
        uint256 blockNumber;
        uint256 blockTimestamp;
        bool active;
        uint256 value;  // Associated value (0-1,000,000 for absolute, or basis points for %, type(uint256).max = no value)
    }


    struct OfficialEntityGroup {
        mapping(address => OfficialEntityStruct) entitiesByAddress; // Maps entity address to its details
        address[] entityList; // List of entity addresses for iteration
    }


    struct AdminTypeRegistry {
       mapping(string  => bool)  isRegistered;     // internally a hash key but requires string for lookup
       mapping(bytes32 => bool)  isHashRegistered; // slightly faster pre-hahsed lookup
       string[] registeredAdminTypes;
       mapping(bytes32 => string) nameByHash;       // Reverse lookup from hash to original string
    }

    struct ChainedEntityStruct {
        address entityAddress;
        address parent;
        uint8[] feeTypes;      // Array of fee type bytes [0, 1, 2, 3, 4, ...]
        uint256[] feeAmounts;  // Parallel array: amounts (absolute or basis points)
        uint8[] feeFlags;      // Parallel array: bit0=isPercent, bit1=isTaker
        bool active;
        bool locked;     // Temporary lock by ancestors - can be unlocked
        bool permanentlyLocked;  // Permanent lock by Super after 6 months - IRREVERSIBLE
        uint256 blockNumber;
        uint256 blockTimestamp;
        string entityName;  // Human-readable name
        string entityID;    // Additional identifier (tax ID, registration #, etc)
    }

    struct CalculatedEntityAmount {
        address entityAddress;
        uint256 amount;  // Calculated amount for the requested feeType
    }

    mapping(bytes32 => OfficialEntityGroup) private officialEntityGroupsByHash;


    // NEW structure to SUPPORT validateAdminType


     AdminTypeRegistry private adminTypeRegistry;
    
    // Project can lock itself by removing its super.  
    // It can lock from platform for updates to SmartContract entities by permanently locking with this var
    // Platform may optionally permanently lock itself out of project as well.
    bool public platformAccessPermanentlyRevoked;
    uint256 public projectLockTimestamp;
    // address public remoteController; // Hub address for admin verification - ALWAYS "this" for now
    string public platformName;
    string public projectName;  // Project name (fixed at deployment)
    string public projectId;    // Project ID (fixed at deployment)
    // ⚠️ CRITICAL: deploymentTimestamp is NOT immutable to enable CREATE2 verification
    // Etherscan/BscScan verification fails for CREATE2 factory deployments when immutable values
    // (like block.timestamp) change between deployments, causing different bytecode each time.
    // Making this a regular storage variable allows deterministic bytecode for cross-chain CREATE2.
    uint256 public deploymentTimestamp; // Deployment time - used for 6-month lock delay
    
    /// @notice The platform controller for this project (for validating platform treasurer and factory)
    /// @dev For the platform's own controller, this points to itself. For project controllers, points to platform controller.
    address public immutable PLATFORM_CONTROLLER;
    
    // Entity type string constants - reused to save bytecode
    string private constant STR_TREASURY_ADMIN = "TreasuryAdmin";
    string private constant STR_SMART_CONTRACT = "SmartContract";
    string private constant STR_SUPER = "Super";
    string private constant STR_TOKEN = "TokenAdmin";
    string private constant STR_REGISTRAR = "Registrar";
    string private constant STR_LIQUIDITY_POOL = "LiquidityPool";
    string private constant STR_PLATFORM_CONTROLLER = "PLATFORM_CONTROLLER";
    string private constant STR_THIRD_PARTY_REGISTRAR = "ThirdPartyRegistrar";
    
    // Keccak hashes - calculated once to save bytecode
    bytes32 private constant KECCAK_TREASURY_ADMIN = keccak256(bytes(STR_TREASURY_ADMIN));
    bytes32 private constant KECCAK_SMART_CONTRACT = keccak256(bytes(STR_SMART_CONTRACT));
    bytes32 private constant KECCAK_SUPER_ADMIN = keccak256(bytes(STR_SUPER));
    bytes32 private constant KECCAK_PLATFORM_CONTROLLER = keccak256(bytes(STR_PLATFORM_CONTROLLER));
    
    uint256 public constant NO_VALUE = type(uint256).max;  // Sentinel value indicating "no value set"
    uint256 public constant MAX_VALUE = 1000000000000;  // Maximum allowed value: 1,000,000 USD (in USDC atomic units with 6 decimals: 1M × 1,000,000)
    
    // String action constants for UpdateOfficialEnt event
    string private constant ACTION_STR_ADD = "Add";
    string private constant ACTION_STR_REMOVE = "Remove";

    // Deprecated in favor of platform super tx.origin in init() for bootstrap  or
    // in addOfficialEntity() : msg.sender is existing SmartContract officialEntity, or if self platfomrm controller AND entity is SmartContract, 
    // msg.sender is platform super ortherwise project super.
    //modifier onlySuper() {
    //    if (!isOfficialEntityFast(KECCAK_SUPER_ADMIN, tx.origin)) revert Unauthorized();
    //    _;
    //}


    // Warning! Any official "Super" can call addEntity directly. This is NOT a first line of defense against that.
    //  The only defense there is to make sure your official SCs have their own calls to this controller’s
    //  isOfficialEntity(“Super”) for example BEFORE calling addEntity() or removeEntity()
    //  init() LOCKS this Controller to only allowing TreasAdmins to adding official SCs to begin with.
    //  REMOTE case now allows a smartContract caller unless tx.origin is used
    //  use case of checking that the original human sender is authorized (even through non-official contract calls) 
    //  may be one of the few legitimate uses of tx.origin
    // ✓ To register as official smartContract → You need to be called by an official entity
    // ✗ because you can't be an official entity smartContract → Until that smatcontract calls init() via its own constructor 
    //  therefore we must USE tx.origin for initial registration of smartContracts as a bootstrap
    // Deprecated in favor of platform super or platform smart contract entities.
    //modifier onlySuperOrSCExecutives() {
    //    bool temp = isOfficialEntityFast(KECCAK_SUPER_ADMIN, tx.origin) ||
    //                isOfficialEntityFast(KECCAK_SMART_CONTRACT, msg.sender);
    //    if (!temp) revert Unauthorized();
    //    _;  // run the code block referencing this modifier
    //}


    // to meet the 24K limit, BaseTreasury is now instantiated FIRST - however its concept remains the same - as a BASE class
    // for ElasticTreasuryHUB and ElasticTreasurySPOKE  MasterHub is now an optional, later passed "controller" that must be
    // a separate instantiatedController. This will NOT be used for our needs yet.  In other words, controller is ALWAYS
    // this for now.  initialEntitys are project super entity.  NOT the same as the platform chained entity.
    constructor(
        address projectSuperAddress,
        address platformControllerAddress,
        string memory projectSuperName,
        string memory projectSuperId,
        string memory _projectName,
        string memory _projectId
    ) Recoverable(address(this)) {
        projectName = _projectName;  // Store immutable
        projectId = _projectId;      // Store immutable
        deploymentTimestamp = block.timestamp; // Store for 6-month lock delay calculation
        
        // **Reject if projectSuperAddress is 0x0000**
        if (projectSuperAddress == address(0)) revert NeedsSuperEntity();
        
        // Bootstrap case: address(0) means "self-referential" (platform's own controller)
        // For project controllers: factory passes the platform controller address
        PLATFORM_CONTROLLER = (platformControllerAddress == address(0)) ? address(this) : platformControllerAddress;
        
        // Derive platformName: if self-referential, use projectName; otherwise fetch from platform controller
        if (PLATFORM_CONTROLLER == address(this)) {
            // This IS the platform controller - use projectName as platformName
            platformName = _projectName;
        } else {
            // This is a project controller - fetch platformName from the platform controller
            // Cast to Controller (not IController) since platformName is a public variable with auto-generated getter
            platformName = Controller(PLATFORM_CONTROLLER).platformName();
        }
        
        // Register default admin types  (not essential, self-adding, here for dynamic UX only when empty for clarity) 
        string[8] memory defaultTypes = [STR_TREASURY_ADMIN, STR_SMART_CONTRACT, STR_SUPER, STR_PLATFORM_CONTROLLER, STR_TOKEN, STR_REGISTRAR, STR_THIRD_PARTY_REGISTRAR, STR_LIQUIDITY_POOL];
        for (uint256 i = 0; i < defaultTypes.length; i++) {
            addAdminType(defaultTypes[i]);
        }
        // Use passed entity name/ID or defaults if empty
        string memory superName = bytes(projectSuperName).length > 0 ? projectSuperName : "Multi-Sig Officer";
        string memory superID = bytes(projectSuperId).length > 0 ? projectSuperId : "Multi-Sig Execs";
        addOfficialEntityNow(KECCAK_SUPER_ADMIN, projectSuperAddress, superName, superID, NO_VALUE);
        addOfficialEntityNow(KECCAK_TREASURY_ADMIN, projectSuperAddress, superName, superID, NO_VALUE);
        
        // Register platform controller as official entity (for reference and validation)
        addOfficialEntityNow(KECCAK_PLATFORM_CONTROLLER, PLATFORM_CONTROLLER, platformName, STR_PLATFORM_CONTROLLER, NO_VALUE);
        
        // Fee hierarchies are now managed by FeeManager (deployed separately)
    }


    // 🆕 Init window state for constructor self-registration during factory deployAll
    bool public initWindowOpen = false;
    address public initWindowOrigin;  // tx.origin authorized during window
    
    /// @notice Open init window to allow constructor self-registration (factory only)
    /// @dev Window is tied to tx.origin - only contracts deployed by that EOA can register
    /// @return success True if opened, false if already open
    function openInit() external returns (bool success) {
        if (platformAccessPermanentlyRevoked) revert NoPlatformAccess();
        
        // Only platform SmartContract can open - REVERT if unauthorized
        if (!isPlatformAdmin(msg.sender, KECCAK_SMART_CONTRACT)) {
            revert Unauthorized();
        }
        
        if (initWindowOpen) return false; // Already open (benign)
        
        initWindowOpen = true;
        initWindowOrigin = tx.origin;  // Capture deployer's EOA
        return true;
    }
    
    /// @notice Close init window (callable by anyone, no checksum needed)
    /// @return success True if closed successfully, false if not open
    function closeInit() external returns (bool success) {
        if (!initWindowOpen) return false; // Not open (benign)
        
        initWindowOpen = false;
        initWindowOrigin = address(0);
        return true;
    }
    
    /// @notice Get entity count for analytics
    function getEntityCount(bytes32 adminTypeHash) external view returns (uint256) {
        return officialEntityGroupsByHash[adminTypeHash].entityList.length;
    }

    /// @notice Register a SmartContract entity during deployment/initialization
    /// @dev 🔒 SECURITY: Three authorized paths:
    ///  A) Manual Mode: tx.origin is super ONLY if THIS is the platform controller (self-only)
    ///  B) Auto Mode: msg.sender is registered as a SmartContract in platform controller
    ///  C) Constructor Mode: init window is open (checksum on closeInit protects against exploits)
    ///      NOTE: Originally checked code.length == 0 to enforce constructor-only, but removed
    ///            because complex call chains or post-constructor init may be legitimate.
    ///            closeInit() checksum is the real security mechanism.
    /// @dev Contracts self-register via ExecutivePeerTreasury constructor calling init()
    // tx.origin usage is STRICTLY limited to platform bootstrap.
    // After Super removal / lock, (upon platform maturity) no tx.origin–based authorization remains. 
    // However platform super is also used to add new features to projects.  Once removed, new existing tokens will 
    // be able to receive new features, but they will be 100% sovereign at that time.
    // Regarding any EXISTING platform smartcontract to have the authority to add new entities: 
    //   "Platform SmartContract compromise implies total system compromise by design."
    function init(address officialSmartContractAddress, string calldata contractName) external  {   // onlySuperOrSCExecutives
        if (platformAccessPermanentlyRevoked) revert NoPlatformAccess();
        // 🔒 SECURITY: Three authorized paths:
        // A) Manual Mode: tx.origin is super ONLY if THIS is the platform controller (self-only)
        // B) Auto Mode: msg.sender is registered as a SmartContract in platform controller
        // C) Constructor Mode: init window open (no code.length check - see docstring)
        
        // Check A: Is this platform controller and tx.origin a super? (manual deployment to platform only)
        bool isPlatformSuperSelf = (PLATFORM_CONTROLLER == address(this)) 
            && isOfficialEntityFast(KECCAK_SUPER_ADMIN, tx.origin);
        
        // Check B: Is msg.sender a registered Platform SmartContract? (factory deployment)
        bool isOfficialPlatformSmartContract = false;
        if (!isPlatformSuperSelf) {
            try IController(PLATFORM_CONTROLLER).isOfficialEntityFast(KECCAK_SMART_CONTRACT, msg.sender) returns (bool result) {
                isOfficialPlatformSmartContract = result;
            } catch {
                // Not registered as factory
            }
        }
        
        // Check C: Init window open (checksum validation happens on closeInit)
        // Removed: && officialSmartContractAddress.code.length == 0
        // Reason: May prevent legitimate post-constructor or complex call-chain scenarios
            // Check C: Init window open AND caller's tx.origin matches window origin
            // SECURITY: Only contracts deployed by the authorized origin can register during window
            bool isConstructorDuringOpenWindow = initWindowOpen && tx.origin == initWindowOrigin;
        
        if (!isPlatformSuperSelf && !isOfficialPlatformSmartContract && !isConstructorDuringOpenWindow) {
            revert OnlyPlatformSCOrOpenWindow();
        }
        
        addOfficialEntityNow(KECCAK_SMART_CONTRACT, officialSmartContractAddress, contractName, "", NO_VALUE);  // may exist, if token, symbol will be added.
    }

    /**
    * ⚠️ WARNING:
    * After this function is called:
    * - NO SmartContract enity can be added to the project
    * - NO SmartContract centity an be removed from the project
    * - YES OTHER admin entities can continue to be added, removed, or modified until the PROJECT removes its own SUPER!
    * - This action is PERMANENT and IRREVERSIBLE
    *
    * This exists to provide cryptographic finality guarantees
    * to investors, regulators, and counterparties.
    */
    function lockPlatformAccessPermanently() external {
        if (platformAccessPermanentlyRevoked) revert PlatformAccessAlreadyRevoked();
        bool isProjectSuper = isOfficialEntityFast(KECCAK_SUPER_ADMIN, msg.sender);
        bool isPlatformSuper = isPlatformAdmin(msg.sender, KECCAK_SUPER_ADMIN);
        if (!isProjectSuper && !isPlatformSuper) {
            revert Unauthorized();
        }
        platformAccessPermanentlyRevoked = true;
        projectLockTimestamp = block.timestamp;
        emit PlatformAccessPermanentlyRevoked(
            msg.sender,
            isPlatformSuper,
            block.timestamp
        );
    }




    /* NOT USED
    function remotelyManage(address _controller) external onlySuperOrSCExecutives {
        bool isRemotelyManaged = (_controller != address(0) && _controller != address(this));
        if (isRemotelyManaged) {
            remoteController = _controller;
        }
        else {
            remoteController = address(this);  // not used if isRemotelyManaged is false
        }
        changeController(remoteController);
    } */



    //function doesRemoteControllerManageAllOfficials() internal view returns (bool) {
    //    return controller != address(this);
    //}



    ///
    //   OFFICIAL ENTITIES
    //
    //

        

        // Inline modifier replaces validateAdminType function (saves ~150 bytes)
        modifier validAdmin(bytes32 adminHash) {
            if (!adminTypeRegistry.isHashRegistered[adminHash]) revert InvalidAdminType();
            _;
        }


        function addAdminType(string memory adminType) internal returns (bool) {
            if (!adminTypeRegistry.isRegistered[adminType]) {
                // to support remote case, let a TreasuryAdmin add too, since “SmartContract” is not sensed for remote
                // chained transaction caller:  EOA ⇒ contract A == > contract B (here) ⇒ remote controller (A not sensed)
                // require(isOfficialEntity(“SmartContract”,msg.sender),”Only official SC can add new Officl type”);
                bytes32 hash = keccak256(bytes(adminType));
                adminTypeRegistry.isRegistered[adminType] = true;
                adminTypeRegistry.isHashRegistered[hash] = true;
                adminTypeRegistry.nameByHash[hash] = adminType;
                adminTypeRegistry.registeredAdminTypes.push(adminType);
                return true;
            }
            return false;
        }


        // Retrieve all registered admin types
        function getRegisteredAdminTypes() external view returns (string[] memory) {
            return adminTypeRegistry.registeredAdminTypes;
        }

        /**
         * @notice Add an official entity (Super permission required)
         * @dev SPECIAL SECURITY: No new types can be added except by EXISTING SmartContract entities or platform super entities.
         *      Platform super cannot remove, adding by platform superis reserved for future feature updates. However no existing features may be modified.
         *      This creates a higher security tier for critical platform operations.
         * @param adminType Type of entity (e.g., "TreasuryAdmin", "Super", "SmartContract")
         * @param entityAddr Address of the entity to add
         * @param label Human-readable name
         * @param nationalIdOrSC National ID or smart contract identifier
         */
       function addOfficialEntity(string calldata adminType, address entityAddr, string calldata label,string calldata nationalIdOrSC) external returns (bool) { // onlySuper  
            bytes32 adminHash = keccak256(bytes(adminType));
            // if (!adminTypeRegistry.isHashRegistered[adminHash]) revert InvalidAdminType();
            // SECURITY: PLATFORM_CONTROLLER can only be managed by existing PLATFORM_CONTROLLER super 
            // (although platformController is managed outside officialentities map. It is stored here prery much unnecessarily so the check is moot except to avoid confusion)
            // 🔒 SECURITY: No SmartContract entity type can be added except by PLATFORM_CONTROLLER super or EXISTING SmartContract official entities
            // Prevents projects from adding rogue contracts that are not platform authorized or compatible and may bypass fees
            // These next conditions not relevant anymore since only EXISTING smart contract entities OR platform super entities can add new entities.
            bool spec = (adminHash == KECCAK_PLATFORM_CONTROLLER || adminHash == KECCAK_SMART_CONTRACT);
            bool isOfclSC = isOfficialEntityFast(KECCAK_SMART_CONTRACT, msg.sender);
            bool needsLord = spec && !isOfclSC; // specifically the controller factory is all that should add outside of init 
            if (needsLord) {
                if (platformAccessPermanentlyRevoked) revert NoPlatformAccess();
                if (!isPlatformAdmin(msg.sender, KECCAK_SMART_CONTRACT) && !isPlatformAdmin(msg.sender, KECCAK_SUPER_ADMIN)) revert OnlyPlatformSuperOrSC();
            }
            else {
                // ✅ FIX: Allow SmartContracts OR Super Admins to add regular entities
                if (!isOfclSC && !isOfficialEntityFast(KECCAK_SUPER_ADMIN, msg.sender)) revert OnlySuper();
            }
            // ✅ auto-register new admin type if caller is authorized (per rules above)
            // only if the caller is an existing SmartContract official entity
             if (!adminTypeRegistry.isHashRegistered[adminHash]) {
                if (isOfclSC) { 
                    addAdminType(adminType); // internal; will mark isHashRegistered + push into list
                }
                else {
                    revert InvalidAdminType();
                }
                // (adminHash remains correct because it's keccak256(adminType))
            }
            return addOfficialEntityNow(adminHash, entityAddr, label, nationalIdOrSC, NO_VALUE);
        }

        // Add official entity with an associated value
        function addOfficialEntityWithValue(string calldata adminType, address entityAddr, string calldata label, string calldata nationalIdOrSC, uint256 value) external  returns (bool) { // onlySuper
            bytes32 adminHash = keccak256(bytes(adminType));
            if (value > MAX_VALUE) revert ValExceedsMax();
            // if (!adminTypeRegistry.isHashRegistered[adminHash]) revert InvalidAdminType();
            // SECURITY: PLATFORM_CONTROLLER can only be managed by existing PLATFORM_CONTROLLER super
            // 🔒 SECURITY: No entity can be added except by PLATFORM_CONTROLLER super or EXISTING SmartContract official entities
            // Prevents projects from adding rogue tokens/contracts that bypass fees
            bool spec = (adminHash == KECCAK_PLATFORM_CONTROLLER || adminHash == KECCAK_SMART_CONTRACT);
            bool isOfclSC = isOfficialEntityFast(KECCAK_SMART_CONTRACT, msg.sender);
            bool needsLord = spec && !isOfclSC; // specifically the controller factory is all that should add outside of init 
            if (needsLord) {
                if (platformAccessPermanentlyRevoked) revert NoPlatformAccess();
                if (!isPlatformAdmin(msg.sender, KECCAK_SMART_CONTRACT) && !isPlatformAdmin(msg.sender, KECCAK_SUPER_ADMIN)) revert OnlyPlatformSuperOrSC();
            }
            else {
                // ✅ FIX: Allow SmartContracts OR Super Admins to add regular entities
                if (!isOfclSC && !isOfficialEntityFast(KECCAK_SUPER_ADMIN, msg.sender)) revert OnlySuper();
            }
            // ✅ auto-register new admin type if caller is authorized (per rules above)
            // only if the caller is an existing SmartContract official entity
            if (!adminTypeRegistry.isHashRegistered[adminHash]) {
                if (isOfclSC) { 
                    addAdminType(adminType); // internal; will mark isHashRegistered + push into list
                }
                else {
                    revert InvalidAdminType();
                }
                // (adminHash remains correct because it's keccak256(adminType))
            }
            return addOfficialEntityNow(adminHash, entityAddr, label, nationalIdOrSC, value);
        }

       
       function addOfficialEntityNow(bytes32 adminHash, address entityAddr, string memory label, string memory nationalIdOrSCSymbol, uint256 value) internal returns (bool) {
            //if (doesRemoteControllerManageAllOfficials()) {
            //    // For remote controller, route based on whether value is set
            //    if (value == NO_VALUE) {
            //        return Controller(controller).addOfficialEntity(adminType, entityAddr, label, nationalIdOrSCSymbol);
            //    } else {
            //        return Controller(controller).addOfficialEntityWithValue(adminType, entityAddr, label, nationalIdOrSCSymbol, value);
            //    }
            //}
            if (entityAddr == address(0)) revert BadAddr();
            if (bytes(label).length == 0) {
                if (entityAddr.code.length > 0) {
                    try IERC20SymbolAndName(entityAddr).name() returns (string memory s) {
                        label = bytes(s).length > 0 ? s : "SC not token";
                    } catch {
                        label = "SC not token";
                    }
                }
                else {
                    label = "SC not token";
                }
            }
            if (bytes(nationalIdOrSCSymbol).length == 0) {
                if (entityAddr.code.length > 0) {
                    try IERC20SymbolAndName(entityAddr).symbol() returns (string memory s) {
                        nationalIdOrSCSymbol = bytes(s).length > 0 ? s : "SC no token symbol";
                    } catch {
                        nationalIdOrSCSymbol = "SC not token";
                    }
                } else {
                    nationalIdOrSCSymbol = "wallet not SC";
                }
            }
            // Admin type already validated by caller - use hash directly
            OfficialEntityGroup storage group = officialEntityGroupsByHash[adminHash];
            
            // Check if entity already exists in mapping (even if inactive)
            bool entityExists = group.entitiesByAddress[entityAddr].pubAddress != address(0);
            
            if (entityExists) {
                // Entity exists - either active or inactive
                if (group.entitiesByAddress[entityAddr].active) {
                    // Entity is active - handle value updates
                    uint256 existingValue = group.entitiesByAddress[entityAddr].value;
                    
                    // Prevent changing from value to NO_VALUE or vice versa
                    if ((existingValue == NO_VALUE && value != NO_VALUE) || 
                        (existingValue != NO_VALUE && value == NO_VALUE)) revert NoValRemove();
                    
                    // Allow updating to a different value (both must be real values)
                    if (value != NO_VALUE && existingValue != value) {
                        group.entitiesByAddress[entityAddr].value = value;
                        emit UpdateOfficialEnt(entityAddr, msg.sender, adminHash, "UpdateValue", label, nationalIdOrSCSymbol, block.timestamp, true, value);
                        return true;
                    }
                    
                    return false;  // Already exists with same value
                } else {
                    // Entity exists but is INACTIVE - reactivate WITHOUT pushing to array again
                    group.entitiesByAddress[entityAddr].fullNameOfEntityOrLabel = label;
                    group.entitiesByAddress[entityAddr].nationalIdOfEntity = nationalIdOrSCSymbol;
                    group.entitiesByAddress[entityAddr].blockNumber = block.number;
                    group.entitiesByAddress[entityAddr].blockTimestamp = block.timestamp;
                    group.entitiesByAddress[entityAddr].active = true;
                    group.entitiesByAddress[entityAddr].value = value;
                    
                    emit UpdateOfficialEnt(entityAddr, msg.sender, adminHash, "Reactivate", label, nationalIdOrSCSymbol, block.timestamp, true, value);
                    return true;
                }
            }
            
            // Brand new entity - add to mapping AND array
            group.entitiesByAddress[entityAddr] = OfficialEntityStruct(label, nationalIdOrSCSymbol, entityAddr, block.number, block.timestamp, true, value);
            group.entityList.push(entityAddr);
            
            emit UpdateOfficialEnt(entityAddr, msg.sender, adminHash, ACTION_STR_ADD, label, nationalIdOrSCSymbol, block.timestamp, true, value);
            return true;
        }

        function removeOfficialEntity(string calldata adminType, address entityAddr) external returns (bool) { // onlySuper
            bytes32 adminHash = keccak256(bytes(adminType));
            bool spec = (adminHash == KECCAK_PLATFORM_CONTROLLER || adminHash == KECCAK_SMART_CONTRACT);
            if (platformAccessPermanentlyRevoked && spec) revert NoPlatformAccess(); // or a project trying to remove a SmartContract entity
            if (entityAddr == address(0)) revert BadAddr();
            
            if (!adminTypeRegistry.isHashRegistered[adminHash]) revert InvalidAdminType();
             // 🔒 SECURITY: No SmartContract entity can be removed except by EXISTING SmartContract official entities
             //  UNLESS the controller is also the platform controller (self-only).
            
            bool needsLord = spec && !isOfficialEntityFast(KECCAK_SMART_CONTRACT, msg.sender);
            if (needsLord) {
                // Project revamps/updates handled via platform permissions to remove old SmartContract 
                // entities (which projects can revoke via permLock)
                if (!isPlatformAdmin(msg.sender, KECCAK_SMART_CONTRACT) && !isPlatformAdmin(msg.sender, KECCAK_SUPER_ADMIN)) revert OnlyPlatformSuperOrSC();
            }
            else {
                // 🔒 SECURITY: SmartContracts CANNOT remove regular entities (unlike addOfficialEntity where they can add)
                // SCs NEED add permission for bootstrap/initialization, but NEVER need remove permission
                if (!isOfficialEntityFast(KECCAK_SUPER_ADMIN, msg.sender)) revert OnlySuper();
            }
            
            OfficialEntityGroup storage group = officialEntityGroupsByHash[adminHash];
            if (!group.entitiesByAddress[entityAddr].active) {
                return false;
            }
            // Soft-delete by marking inactive, but retain in list for history
            group.entitiesByAddress[entityAddr].active = false;
            emit UpdateOfficialEnt(entityAddr, msg.sender, adminHash, ACTION_STR_REMOVE,group.entitiesByAddress[entityAddr].fullNameOfEntityOrLabel,group.entitiesByAddress[entityAddr].nationalIdOfEntity,block.timestamp,false,group.entitiesByAddress[entityAddr].value);
            return true;
        }

        function isOfficialEntityFast(bytes32 hashedAdminType, address entityAddr) public view returns (bool) {
            if (entityAddr == address(0)) revert BadAddr();
             if (!adminTypeRegistry.isHashRegistered[hashedAdminType]) revert InvalidAdminType();
            return officialEntityGroupsByHash[hashedAdminType].entitiesByAddress[entityAddr].active;
        }

        function isOfficialEntity(string calldata adminType, address entityAddr) external view returns (bool) {
            if (entityAddr == address(0)) revert BadAddr();
            bytes32 adminHash = keccak256(bytes(adminType));
            if (!adminTypeRegistry.isHashRegistered[adminHash]) revert InvalidAdminType();
            return officialEntityGroupsByHash[adminHash].entitiesByAddress[entityAddr].active;
        }

        /// @notice Check if an address is a TreasuryAdmin in the platform controller
        /// @dev This is the new standard way to check platform treasurer privileges
        /// @param addr The address to check
        /// @return true if the address is a TreasuryAdmin in the platform controller
        function isPlatformAdmin(address addr, bytes32 adminHash) public view returns (bool) {
            // Bootstrap case: if we ARE the platform controller, check locally
            if (PLATFORM_CONTROLLER == address(this)) {
                return isOfficialEntityFast(adminHash, addr);
            }
            
            // Otherwise, check if addr is TreasuryAdmin in the platform controller
            return  IController(PLATFORM_CONTROLLER).isOfficialEntityFast(adminHash, addr);
        }

        function isPlatform() external view returns (bool) {
            return address(this) == PLATFORM_CONTROLLER;
        }

        function getOfficialEntity(string calldata adminType, address entityAddr) external view returns (OfficialEntityStruct memory) {
            if (entityAddr == address(0)) revert BadAddr();
            bytes32 adminHash = keccak256(bytes(adminType));
            if (!adminTypeRegistry.isHashRegistered[adminHash]) revert InvalidAdminType();
            OfficialEntityStruct storage entity = officialEntityGroupsByHash[adminHash].entitiesByAddress[entityAddr];
            if (!entity.active) revert NoEntity();
            return entity;
        }

        function getAllOfficialEntities(string calldata adminType, bool includeInactive) external view returns (OfficialEntityStruct[] memory) {
            bytes32 adminHash = keccak256(bytes(adminType));
            if (!adminTypeRegistry.isHashRegistered[adminHash]) revert InvalidAdminType();
            OfficialEntityGroup storage group = officialEntityGroupsByHash[adminHash];
            // First count entities based on the includeInactive parameter
            uint256 entityCount = 0;
            for (uint256 i = 0; i < group.entityList.length; i++) {
                address entityAddr = group.entityList[i];
                if (includeInactive || group.entitiesByAddress[entityAddr].active) {
                    entityCount++;
                }
            }
            // Then create array of exactly the right size and fill it
            OfficialEntityStruct[] memory filteredEntities = new OfficialEntityStruct[](entityCount);
            uint256 counter = 0;
            for (uint256 i = 0; i < group.entityList.length; i++) {
                address entityAddr = group.entityList[i];
                if (includeInactive || group.entitiesByAddress[entityAddr].active) {
                    filteredEntities[counter] = group.entitiesByAddress[entityAddr];
                    counter++;
                }
            }
            return filteredEntities;
        }

        function isOfficialEntityPlusNotEntityFast(bytes32 adminType1, address entityAddr1,bytes32 adminType2, address entityAddr2, bool isAnd) external view returns (bool) {
            if (isAnd) {
                return isOfficialEntityFast(adminType1, entityAddr1) && !isOfficialEntityFast(adminType2, entityAddr2);
            } else {
                return isOfficialEntityFast(adminType1, entityAddr1) || !isOfficialEntityFast(adminType2, entityAddr2);
            }
        }


        function isOfficialDoubleEntityFast(bytes32 adminType1, address entityAddr1,bytes32 adminType2, address entityAddr2, bool isAnd) external view returns (bool) {
            if (isAnd) {
                return isOfficialEntityFast(adminType1, entityAddr1) && isOfficialEntityFast(adminType2, entityAddr2);
            } else {
                return isOfficialEntityFast(adminType1, entityAddr1) || isOfficialEntityFast(adminType2, entityAddr2);
            }
        }

        // Fast triple entity check with bytes32
        function isOfficialTripleEntityFast(bytes32 adminType1, address entityAddr1, bytes32 adminType2, address entityAddr2,
            bytes32 adminType3, address entityAddr3, bool isAnd) external view returns (bool) {
            if (isAnd) {
                return isOfficialEntityFast(adminType1, entityAddr1) 
                    && isOfficialEntityFast(adminType2, entityAddr2) 
                    && isOfficialEntityFast(adminType3, entityAddr3);
            } else {
                return isOfficialEntityFast(adminType1, entityAddr1) 
                    || isOfficialEntityFast(adminType2, entityAddr2) 
                    || isOfficialEntityFast(adminType3, entityAddr3);
            }
        }

      function isOfficialQuadrupleEntityFast(bytes32 adminType1, address entityAddr1,bytes32 adminType2, address entityAddr2,bytes32 adminType3, address entityAddr3,
            bytes32 adminType4, address entityAddr4,bool isAnd) external view returns (bool) {
            if (isAnd) {
                return isOfficialEntityFast(adminType1, entityAddr1) 
                    && isOfficialEntityFast(adminType2, entityAddr2)
                    && isOfficialEntityFast(adminType3, entityAddr3) 
                    && isOfficialEntityFast(adminType4, entityAddr4);
            } else {
                return isOfficialEntityFast(adminType1, entityAddr1)
                    || isOfficialEntityFast(adminType2, entityAddr2)
                    || isOfficialEntityFast(adminType3, entityAddr3)
                    || isOfficialEntityFast(adminType4, entityAddr4);
            }
        }

    //
    // END OFFICIAL ENTITIES
    //

    // ========== FEE MANAGEMENT ==========
    // All fee management (chained entities) moved to FeeManager.sol
    // Access via IFeeManager interface

        /// @notice Fee management functions removed - use FeeManager contract instead
        /// All fee calculation, distribution, and chained entity management moved to FeeManager.sol
        /// See IFeeManager interface for available functions

    // END CHAINED ENTITIES
    //

        


    // No receiving of accidental or unsolicited eth here
    // See below for a payable method for SALES purposes and OTHER purposes (see BELOW).
    // receive() external payable {  // <== DO NOT IMPLEMENT, LEAVE COMMENTED
    //    ethBalances[msg.sender].totalReceivedThatIsReversible += msg.value;
    //}

}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    /**
     * @dev An operation with an ERC20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
     * value, non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data);
        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
    }
}

// SPDX-License-Identifier: CLOSED LICENSE COPYRIGHT 2025
// OFFICAL DEL NORTE NETWORK COMPONENT
// Designed By Ken Silverman for Del Norte.  Implementation help from Tony Sparks
// Compilation help from Maleeha Naveed. May 5th, 2025

pragma solidity 0.8.30;


import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IController.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";


/// @title ReversibleRecoveryBase
/// @notice Base contract tracking / reversing accidental ETH/ERC20 transfers with admin authorization
abstract contract Recoverable {

    using SafeERC20 for IERC20;

    // STRUCTS


    struct ReversibleUserBalance {
        uint256 totalReceivedThatIsReversible;
        uint256 totalReversed;
        uint256 totalReversals;
    }


    // -----------------------------
    // STORAGE
    // -----------------------------


    address public controller;  // Address of the Controller contract (must implement IController)
    uint256 public ADMIN_FEE_FIXED = 10 ** 17; // 0.1 ETH
    uint256 public totalAdminFeesCollected;


    mapping(address => ReversibleUserBalance) public reversibleEthBalances;
    mapping(address => mapping(address => ReversibleUserBalance)) public reversibleTokenBalances;


    // -----------------------------
    // EVENTS
    // -----------------------------
    event TransferReversed(address indexed user, uint256 refundAmount, address tokenSC, uint256 adminFee);
    event AdminFeeUpdated(uint256 newFee);
    event ControllerChanged(address newController);


     modifier onlyBTExecutives() {
        bool temp = IController(controller).isOfficialEntity("TreasuryAdmin", msg.sender) ||
                    IController(controller).isOfficialEntity("SmartContract", msg.sender);
        require(temp, "Unauthorized access");
        _;  // run the code block referencing this modifier
    }


    // -----------------------------
    // CONSTRUCTOR
    // -----------------------------
    constructor(address _controller) {
        require(_controller != address(0), "Controller address cannot be zero");
        controller = _controller;
    }


    // -----------------------------
    // EXTERNAL METHODS
    // -----------------------------
    function manualUpdateReversibleBalanceETH(address userAddress, uint256 amount)
        external onlyBTExecutives  {
        reversibleEthBalances[userAddress].totalReceivedThatIsReversible += amount;
    }




    function manualUpdateReversibleBalanceERC20(address userAddress, uint256 amount, address tokenSC)
        external onlyBTExecutives {
        reversibleTokenBalances[tokenSC][userAddress].totalReceivedThatIsReversible += amount;
    }


    function reverseAccidentalETH() external payable  {
        require(msg.value >= ADMIN_FEE_FIXED, "Insufficient admin fee");
        require(!IController(controller).isOfficialEntity("Registrar", msg.sender),
            "Registrars/launchpads may not be allowed to reverse any amounts they send.");
        ReversibleUserBalance storage balance = reversibleEthBalances[msg.sender];
        uint256 refundAmount = balance.totalReceivedThatIsReversible - balance.totalReversed;
        require(refundAmount > 0, "Nothing to refund");
        // Update state before external call
        balance.totalReversed += refundAmount;
        balance.totalReversals += 1;
        totalAdminFeesCollected += msg.value;
        // Perform the external call
        (bool success, ) = msg.sender.call{value: refundAmount}("");
        require(success, "Ether transfer failed");
        emit TransferReversed(msg.sender, refundAmount, address(0), msg.value);
    }



    function reverseAccidentalERC20(address tokenSC) external payable {
        require(msg.value >= ADMIN_FEE_FIXED, "Insufficient admin fee");
        require(!IController(controller).isOfficialEntity("Registrar", msg.sender), "Registrars/launchpads may not reverse any amounts they send.");
        ReversibleUserBalance storage balance = reversibleTokenBalances[tokenSC][msg.sender];
        uint256 refundAmount = balance.totalReceivedThatIsReversible - balance.totalReversed;
        require(refundAmount > 0, "Nothing to refund");
        // Update state before external call
        balance.totalReversed += refundAmount;
        balance.totalReversals += 1;
        totalAdminFeesCollected += msg.value;
        // Perform the external call
        IERC20(tokenSC).safeTransfer(msg.sender, refundAmount);
        emit TransferReversed(msg.sender, refundAmount, tokenSC, msg.value);
  }


    function changeAdminFee(uint256 newFee) external onlyBTExecutives {
        ADMIN_FEE_FIXED = newFee;
        emit AdminFeeUpdated(newFee);
    }


   function changeController(address remote) internal {
        controller = remote;
        emit ControllerChanged(remote);
   }
}

// SPDX-License-Identifier: UNLICENSED
// ============================================================
//  EquityMint.org — Official Sovereign Issuance Contract
//  © Copyright 2025 US Fintech LLC
//  All Rights Reserved.
// ------------------------------------------------------------
//  This contract is part of the EquityMint.org RWA platform,
//  built on the DataCloud OS issuance engine. This file and all
//  related logic are proprietary intellectual property of
//  US Fintech LLC. EquityMint.com and all other domains are not
//  authorized sources of this technology.
//
//  Licensing & Authorized Use:
//  - Deployments are permitted ONLY through the official
//    EquityMint DataCloud OS Sovereign Deployment Engine.
//  - Each issuer receives a sovereign copy with identical
//    canonical comments and legal metadata.
//  - White-labeling is prohibited unless explicitly authorized
//    by written agreement with US Fintech LLC.
//  - Any deployment, modification, or derivative work that does
//    NOT include this header is an unauthorized use.
//  - Any such unauthorized deployment or derivation will be
//    subject to enforcement and legal remedies, including civil
//    litigation for copyright infringement, against the deployer
//    and all associated entities.
//
//  Restrictions:
//  - Unauthorized redistribution, modification, resale,
//    rebranding, or misrepresentation is strictly prohibited.
//  - Cloned/forked versions outside the official EquityMint
//    deployment process are not recognized and may violate
//    copyright and licensing terms.
//  - Use of this system for securities offerings requires full
//    legal compliance with applicable exemptions (Reg D 506(b),
//    506(c), Reg S, and Rule 144). Issuers bear all legal
//    responsibility for their own compliance program.
//
//  Authenticity:
//  - Official deployments are cryptographically registered in
//    the EquityMint On-Chain Registry.
//  - Only deployments listed in the registry are recognized as
//    authentic sovereign issuances.
//
//  Contact:
//  - https://EquityMint.org
//  - [email protected]
// ============================================================
//
// Copyright 2025 US Fintech LLC ALL RIGHTS RESERVED.
// Permission to use, copy, modify, or distribute this software is strictly prohibited
// without prior written consent from copyright holder. Violators will be prosecuted to the fullest extent of the law.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE,
// ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// OFFICIAL DEL NORTE NETWORK COMPONENT 
// Provides immediate membership access to platform at different levels. 
// Required Non US or accredited US registration to swap for DTV token. Registration available within 180 days per terms.delnorte.io . 
// Minimally tested Controller Tree for world-wide government administration of, well, anything, including property ownership.
// Designed by Ken Silverman as part of his ElasticTreasury (HUB and SPOKE), PeerTreasury and Controller model. 
// @author Ken Silverman
// This deployment is for  US Fintech, LLC NY.  
// Permission to change metadata stored on blockchain explorers and elsewhere granted to:
// US Fintech, LLC NY only
pragma solidity 0.8.30;

interface IController {
    struct OfficialEntityStruct {
        string fullNameOfEntityOrLabel;
        string nationalIdOfEntity;
        address pubAddress;
        uint256 blockNumber;
        uint256 blockTimestamp;
        bool active;
        uint256 value;  // Associated value (0-1,000,000 for absolute, or basis points for %, type(uint256).max = no value)
    }

    struct ChainedEntityStruct {
        address entityAddress;
        address parent;
        uint8[] feeTypes;      // Array of fee type bytes [0, 1, 2, 3, 4, ...]
        uint256[] feeAmounts;  // Parallel array: amounts (absolute or basis points)
        uint8[] feeFlags;      // Parallel array: bit0=isPercent, bit1=isTaker
        bool active;
        bool locked;     // Temporary lock by ancestors - can be unlocked
        bool permanentlyLocked;  // Permanent lock by Super after 6 months - IRREVERSIBLE
        uint256 blockNumber;
        uint256 blockTimestamp;
        string entityName;  // Human-readable name
        string entityID;    // Additional identifier (tax ID, registration #, etc)
    }

    struct CalculatedEntityAmount {
        address entityAddress;
        uint256 amount;  // Calculated amount for the requested feeType
    }

    // Internal storage structure for chained entity groups
    struct ChainedEntityGroup {
        mapping(address => ChainedEntityStruct) entitiesByAddress;
        mapping(address => address[]) childrenByParent;
        address[] rootNodes;
    }

    // Entity with fees for addChainedEntity to avoid stack too deep
    struct EntityFeesWithNames {
        address entityAddress;
        address parent;
        uint8[] feeTypes;      // Array of fee type bytes [0, 1, 2, 3, 4, ...]
        uint256[] feeAmounts;  // Parallel array of amounts (same index as feeTypes)
        uint8[] feeFlags;      // Parallel array of flags: bit0=isPercent(0/1), bit1=isTaker(0/1)
        bool locked;
        string entityName;
        string entityID;
    }

    // Official Entity Functions
    function addOfficialEntity(string memory, address, string memory, string memory) external returns (bool);
    function addOfficialEntityWithValue(string memory, address, string memory, string memory, uint256) external returns (bool);
    function removeOfficialEntity(string memory, address) external returns (bool);
    function isOfficialEntity(string memory, address) external view returns (bool);
    function isOfficialEntityFast(bytes32, address) external view returns (bool);
    function isOfficialEntityPlusNotEntityFast(bytes32, address, bytes32, address, bool) external view returns (bool);
    function isOfficialDoubleEntityFast(bytes32, address, bytes32, address, bool) external view returns (bool);
    function isOfficialTripleEntityFast(bytes32, address, bytes32, address, bytes32, address, bool) external view returns (bool);
    function isOfficialQuadrupleEntityFast(bytes32, address,  bytes32, address, bytes32, address, bytes32, address, bool) external view returns (bool);
    function getOfficialEntity(string calldata, address) external view returns (OfficialEntityStruct memory);
    function getAllOfficialEntities(string calldata, bool) external view returns (OfficialEntityStruct[] memory);
    function init(address, string calldata) external;
    function openInit() external returns (bool);
    function closeInit() external returns (bool);
    function getEntityCount(bytes32) external view returns (uint256);
    
    // Platform Controller Functions
    function PLATFORM_CONTROLLER() external view returns (address);
    function isPlatformTreasuryAdmin(address) external view returns (bool);
    function isPlatformAdmin(address, bytes32) external view returns (bool);
    
    // Constants
    function BASIS_POINTS_DIVISOR() external view returns (uint256);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     *
     * CAUTION: See Security Considerations above.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert FailedInnerCall();
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 10000
  },
  "viaIR": true,
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  }
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"projectSuperAddress","type":"address"},{"internalType":"address","name":"platformControllerAddress","type":"address"},{"internalType":"string","name":"projectSuperName","type":"string"},{"internalType":"string","name":"projectSuperId","type":"string"},{"internalType":"string","name":"_projectName","type":"string"},{"internalType":"string","name":"_projectId","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"Bad1stTrsry","type":"error"},{"inputs":[],"name":"BadAddr","type":"error"},{"inputs":[],"name":"BadType","type":"error"},{"inputs":[],"name":"ChildAuthFailed","type":"error"},{"inputs":[],"name":"EntityLocked","type":"error"},{"inputs":[],"name":"EntityNotActive","type":"error"},{"inputs":[],"name":"EntityPermLocked","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"FstTrsyMustBeRoot","type":"error"},{"inputs":[],"name":"GlobalAddLocked","type":"error"},{"inputs":[],"name":"GlobalLockAlreadyActive","type":"error"},{"inputs":[],"name":"InvalidAdminType","type":"error"},{"inputs":[],"name":"InvalidEntity","type":"error"},{"inputs":[],"name":"MustWait6Months","type":"error"},{"inputs":[],"name":"Need1stTrsy","type":"error"},{"inputs":[],"name":"NeedsSuperEntity","type":"error"},{"inputs":[],"name":"NoEntity","type":"error"},{"inputs":[],"name":"NoPlatformAccess","type":"error"},{"inputs":[],"name":"NoValRemove","type":"error"},{"inputs":[],"name":"NotAncestor","type":"error"},{"inputs":[],"name":"NotAncestorOrSelf","type":"error"},{"inputs":[],"name":"NotParentOrSelf","type":"error"},{"inputs":[],"name":"OnlyPT","type":"error"},{"inputs":[],"name":"OnlyParent","type":"error"},{"inputs":[],"name":"OnlyPlatformSCOrOpenWindow","type":"error"},{"inputs":[],"name":"OnlyPlatformSuperOrSC","type":"error"},{"inputs":[],"name":"OnlyProjectOfficialSC","type":"error"},{"inputs":[],"name":"OnlySuper","type":"error"},{"inputs":[],"name":"OnlySuperCanLockRoots","type":"error"},{"inputs":[],"name":"ParentOff","type":"error"},{"inputs":[],"name":"PlatformAccessAlreadyRevoked","type":"error"},{"inputs":[],"name":"RootAuth","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"inputs":[],"name":"SelfRemoveOnly","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ValExceedsMax","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"AdminFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newController","type":"address"}],"name":"ControllerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"bool","name":"byPlatformSuper","type":"bool"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"PlatformAccessPermanentlyRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"refundAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"tokenSC","type":"address"},{"indexed":false,"internalType":"uint256","name":"adminFee","type":"uint256"}],"name":"TransferReversed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"entityAddress","type":"address"},{"indexed":true,"internalType":"address","name":"updater","type":"address"},{"indexed":true,"internalType":"bytes32","name":"entityTypeHash","type":"bytes32"},{"indexed":false,"internalType":"string","name":"action","type":"string"},{"indexed":false,"internalType":"string","name":"fullNameOfEntityOrLabel","type":"string"},{"indexed":false,"internalType":"string","name":"nationalIdOfEntity","type":"string"},{"indexed":false,"internalType":"uint256","name":"blockTimeStamp","type":"uint256"},{"indexed":false,"internalType":"bool","name":"remainsActive","type":"bool"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"UpdateOfficialEnt","type":"event"},{"inputs":[],"name":"ADMIN_FEE_FIXED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CONTRACT_VERSION","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_VALUE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NO_VALUE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PLATFORM_CONTROLLER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"adminType","type":"string"},{"internalType":"address","name":"entityAddr","type":"address"},{"internalType":"string","name":"label","type":"string"},{"internalType":"string","name":"nationalIdOrSC","type":"string"}],"name":"addOfficialEntity","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"adminType","type":"string"},{"internalType":"address","name":"entityAddr","type":"address"},{"internalType":"string","name":"label","type":"string"},{"internalType":"string","name":"nationalIdOrSC","type":"string"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"addOfficialEntityWithValue","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"changeAdminFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"closeInit","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deploymentTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"adminType","type":"string"},{"internalType":"bool","name":"includeInactive","type":"bool"}],"name":"getAllOfficialEntities","outputs":[{"components":[{"internalType":"string","name":"fullNameOfEntityOrLabel","type":"string"},{"internalType":"string","name":"nationalIdOfEntity","type":"string"},{"internalType":"address","name":"pubAddress","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Controller.OfficialEntityStruct[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"adminTypeHash","type":"bytes32"}],"name":"getEntityCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"adminType","type":"string"},{"internalType":"address","name":"entityAddr","type":"address"}],"name":"getOfficialEntity","outputs":[{"components":[{"internalType":"string","name":"fullNameOfEntityOrLabel","type":"string"},{"internalType":"string","name":"nationalIdOfEntity","type":"string"},{"internalType":"address","name":"pubAddress","type":"address"},{"internalType":"uint256","name":"blockNumber","type":"uint256"},{"internalType":"uint256","name":"blockTimestamp","type":"uint256"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"uint256","name":"value","type":"uint256"}],"internalType":"struct Controller.OfficialEntityStruct","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRegisteredAdminTypes","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"officialSmartContractAddress","type":"address"},{"internalType":"string","name":"contractName","type":"string"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"initWindowOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initWindowOrigin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"adminType1","type":"bytes32"},{"internalType":"address","name":"entityAddr1","type":"address"},{"internalType":"bytes32","name":"adminType2","type":"bytes32"},{"internalType":"address","name":"entityAddr2","type":"address"},{"internalType":"bool","name":"isAnd","type":"bool"}],"name":"isOfficialDoubleEntityFast","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"adminType","type":"string"},{"internalType":"address","name":"entityAddr","type":"address"}],"name":"isOfficialEntity","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hashedAdminType","type":"bytes32"},{"internalType":"address","name":"entityAddr","type":"address"}],"name":"isOfficialEntityFast","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"adminType1","type":"bytes32"},{"internalType":"address","name":"entityAddr1","type":"address"},{"internalType":"bytes32","name":"adminType2","type":"bytes32"},{"internalType":"address","name":"entityAddr2","type":"address"},{"internalType":"bool","name":"isAnd","type":"bool"}],"name":"isOfficialEntityPlusNotEntityFast","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"adminType1","type":"bytes32"},{"internalType":"address","name":"entityAddr1","type":"address"},{"internalType":"bytes32","name":"adminType2","type":"bytes32"},{"internalType":"address","name":"entityAddr2","type":"address"},{"internalType":"bytes32","name":"adminType3","type":"bytes32"},{"internalType":"address","name":"entityAddr3","type":"address"},{"internalType":"bytes32","name":"adminType4","type":"bytes32"},{"internalType":"address","name":"entityAddr4","type":"address"},{"internalType":"bool","name":"isAnd","type":"bool"}],"name":"isOfficialQuadrupleEntityFast","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"adminType1","type":"bytes32"},{"internalType":"address","name":"entityAddr1","type":"address"},{"internalType":"bytes32","name":"adminType2","type":"bytes32"},{"internalType":"address","name":"entityAddr2","type":"address"},{"internalType":"bytes32","name":"adminType3","type":"bytes32"},{"internalType":"address","name":"entityAddr3","type":"address"},{"internalType":"bool","name":"isAnd","type":"bool"}],"name":"isOfficialTripleEntityFast","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPlatform","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bytes32","name":"adminHash","type":"bytes32"}],"name":"isPlatformAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lockPlatformAccessPermanently","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"tokenSC","type":"address"}],"name":"manualUpdateReversibleBalanceERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"manualUpdateReversibleBalanceETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"openInit","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"platformAccessPermanentlyRevoked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"platformName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projectId","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projectLockTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"projectName","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"adminType","type":"string"},{"internalType":"address","name":"entityAddr","type":"address"}],"name":"removeOfficialEntity","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenSC","type":"address"}],"name":"reverseAccidentalERC20","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"reverseAccidentalETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"reversibleEthBalances","outputs":[{"internalType":"uint256","name":"totalReceivedThatIsReversible","type":"uint256"},{"internalType":"uint256","name":"totalReversed","type":"uint256"},{"internalType":"uint256","name":"totalReversals","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"reversibleTokenBalances","outputs":[{"internalType":"uint256","name":"totalReceivedThatIsReversible","type":"uint256"},{"internalType":"uint256","name":"totalReversed","type":"uint256"},{"internalType":"uint256","name":"totalReversals","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAdminFeesCollected","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60a0806040523461073d576148f0803803809161001c8285610741565b8339810160c08282031261073d5761003382610764565b9161004060208201610764565b60408201519092906001600160401b03811161073d5781610062918401610778565b60608301519093906001600160401b03811161073d5782610084918501610778565b60808401519093906001600160401b03811161073d57836100a6918301610778565b60a08201519093906001600160401b03811161073d576100c69201610778565b67016345785d8a000060015530156106ee575f80546001600160a01b031916301790556010805460ff1916905582516001600160401b0381116104b45761010e600d546107cd565b601f811161068b575b50806020601f8211600114610627575f9161061c575b508160011b915f199060031b1c191617600d555b8051906001600160401b0382116104b457819061015f600e546107cd565b601f81116105ae575b50602090601f8311600114610548575f9261053d575b50508160011b915f199060031b1c191617600e555b42600f556001600160a01b0385161561052e576001600160a01b0381166105295750305b60808190526001600160a01b0316903082036104c8576101d79150610805565b6040519261010084016001600160401b038111858210176104b4576040526101fd610a3f565b8452604091825161020e8482610741565b600d81526c14db585c9d10dbdb9d1c9858dd609a1b60208201526020860152610235610a6a565b83860152610241610a8d565b606086015282516102528482610741565b600a8152692a37b5b2b720b236b4b760b11b60208201526080860152825161027a8482610741565b60098152682932b3b4b9ba3930b960b91b602082015260a086015282516102a18482610741565b601381527f5468697264506172747952656769737472617200000000000000000000000000602082015260c086015282516102dc8482610741565b600d81526c131a5c5d5a591a5d1e541bdbdb609a1b602082015260e08601525f5b600881101561031f576001906103188160051b880151610ac8565b50016102fd565b508351929361035b931561048357905b80511561045457915b610352838383610346610a6a565b60208151910120610c03565b50610346610a3f565b50610364610a8d565b602081519101209060018060a01b036080511661037f610a8d565b908251905f94600c54610391816107cd565b808552906001811690811561043057506001146103eb575b506103ba836103bf96970384610741565b610c03565b505161385d9081611053823960805181818161028101528181610c5001528181610e7901526129620152f35b600c5f9081529096505f5160206148b05f395f51905f525b87821061041a5750830160200195506103ba6103a9565b6001816020925483858901015201910190610403565b60ff191660208087019190915291151560051b850190910196506103ba90506103a9565b5083516104618582610741565b600f81526e4d756c74692d53696720457865637360881b602082015291610338565b5083516104908582610741565b601181527026bab63a3496a9b4b39027b33334b1b2b960791b60208201529061032f565b634e487b7160e01b5f52604160045260245ffd5b505f60049160405192838092636b90ff0160e11b82525afa801561051e576104f7915f916104fc575b50610805565b6101d7565b61051891503d805f833e6105108183610741565b810190610a17565b5f6104f1565b6040513d5f823e3d90fd5b6101b7565b63775199b360e11b5f5260045ffd5b015190505f8061017e565b600e5f9081528281209350601f198516905b818110610596575090846001959493921061057e575b505050811b01600e55610193565b01515f1960f88460031b161c191690555f8080610570565b9293602060018192878601518155019501930161055a565b600e5f529091507fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd601f840160051c81019160208510610612575b90601f859493920160051c01905b8181106106045750610168565b5f81558493506001016105f7565b90915081906105e9565b90508401515f61012d565b600d5f9081528181209250601f198416905b8181106106735750908360019493921061065b575b5050811b01600d55610141565b8601515f1960f88460031b161c191690555f8061064e565b9192602060018192868b015181550194019201610639565b600d5f527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5601f830160051c810191602084106106e4575b601f0160051c01905b8181106106d95750610117565b5f81556001016106cc565b90915081906106c3565b60405162461bcd60e51b815260206004820152602160248201527f436f6e74726f6c6c657220616464726573732063616e6e6f74206265207a65726044820152606f60f81b6064820152608490fd5b5f80fd5b601f909101601f19168101906001600160401b038211908210176104b457604052565b51906001600160a01b038216820361073d57565b81601f8201121561073d578051906001600160401b0382116104b457604051926107ac601f8401601f191660200185610741565b8284526020838301011161073d57815f9260208093018386015e8301015290565b90600182811c921680156107fb575b60208310146107e757565b634e487b7160e01b5f52602260045260245ffd5b91607f16916107dc565b80519091906001600160401b0381116104b457610823600c546107cd565b601f81116108c5575b50602092601f821160011461086757928192935f9261085c575b50508160011b915f199060031b1c191617600c55565b015190505f80610846565b601f19821693600c5f52805f20915f5b8681106108ad5750836001959610610895575b505050811b01600c55565b01515f1960f88460031b161c191690555f808061088a565b91926020600181928685015181550194019201610877565b600c5f525f5160206148b05f395f51905f52601f830160051c8101916020841061090b575b601f0160051c01905b818110610900575061082c565b5f81556001016108f3565b90915081906108ea565b81519192916001600160401b0381116104b45761093282546107cd565b601f81116109d2575b506020601f821160011461097457819293945f92610969575b50508160011b915f199060031b1c1916179055565b015190505f80610954565b601f19821690835f52805f20915f5b8181106109ba575095836001959697106109a2575b505050811b019055565b01515f1960f88460031b161c191690555f8080610998565b9192602060018192868b015181550194019201610983565b825f5260205f20601f830160051c81019160208410610a0d575b601f0160051c01905b818110610a02575061093b565b5f81556001016109f5565b90915081906109ec565b9060208282031261073d5781516001600160401b03811161073d57610a3c9201610778565b90565b60405190610a4e604083610741565b600d82526c2a3932b0b9bab93ca0b236b4b760991b6020830152565b60405190610a79604083610741565b600582526429bab832b960d91b6020830152565b60405190610a9c604083610741565b601382527f504c4154464f524d5f434f4e54524f4c4c4552000000000000000000000000006020830152565b5f9060405160ff825191602081818601948086835e81016006815203019020541615610af357505090565b908092505160208183209282604051938492835e81016006815203019020600160ff19825416179055805f52600760205260405f20600160ff198254161790555f526009602052610b478160405f20610915565b60085490680100000000000000008210156104b45760018201600855600854821015610ba15760085f52610b9c917ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee301610915565b600190565b634e487b7160e01b5f52603260045260245ffd5b60405190610bc4604083610741565b600c82526b29a1903737ba103a37b5b2b760a11b6020830152565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b926001600160a01b038216915f9190831561104357845115610fca575b815115610f0b575b50845f52600560205260405f20835f528060205260405f20600260018060a01b0391015416610ded5760405160e0810191906001600160401b038311818410176104b4576001926040528681526006602082018581526040830188815260608401438152608085019042825260a0860192888452610cc760c08801955f1987528d5f5289602052610cbe60405f2099518a610915565b518a8901610915565b888060a01b039051166002870190898060a01b0316898060a01b0319825416179055516003860155516004850155511515600584019060ff80198354169115151617905551910155019081549268010000000000000000841015610dd9575060018301808355831015610ba1575f918252602090912090910180546001600160a01b0319168317905560408051935f5160206148d05f395f51905f5292610db9929091610dab91610d789088610741565b600387526210591960ea1b6020880152610d9d6040519760c0895260c0890190610bdf565b908782036020890152610bdf565b908582036040870152610bdf565b92426060820152600160808201525f1960a08201528033940390a4600190565b634e487b7160e01b81526041600452602490fd5b9492939150835f528460205260ff600560405f200154165f14610e63575050505f5260205260405f2060065f19910154148080610e5b575b8115610e44575b50610e35575f90565b6302cf417f60e51b5f5260045ffd5b90501580610e53575b5f610e2c565b506001610e4d565b5f9150610e25565b610db9905f5160206148d05f395f51905f5292949395845f5280602052610e8d8660405f20610915565b845f5280602052610ea482600160405f2001610915565b5f858152602091825260409081902043600382015542600482015560058101805460ff191660011790555f196006909101555160c0808252600a90820152695265616374697661746560b01b60e082015261010091810182905295610dab91870190610bdf565b3b159050610f9d576040516395d89b4160e01b81525f81600481865afa5f9181610f81575b50610f445750610f3e610bb5565b5f610c28565b805115155f03610f3e5750604051610f5d604082610741565b601281527114d0c81b9bc81d1bdad95b881cde5b589bdb60721b6020820152610f3e565b610f969192503d805f833e6105108183610741565b905f610f30565b604051610fab604082610741565b600d81526c77616c6c6574206e6f7420534360981b6020820152610f3e565b9350833b1561103b576040516306fdde0360e01b81525f81600481875afa5f918161101f575b506110045750610ffe610bb5565b93610c20565b8051156110115793610c20565b5061101a610bb5565b610ffe565b6110349192503d805f833e6105108183610741565b905f610ff0565b610ffe610bb5565b6313fe84b160e11b5f5260045ffdfe60806040526004361015610011575f80fd5b5f3560e01c806301d7a0a814611c3c578063063bde2414611c1d57806307f1ef9e14611bd0578063127d532b14611b5a57806315a0d6b714611b3d5780631711e9a014611b215780631ea5283e1461197c57806328f2a80a146119535780632cbc35e41461193957806338b903331461191d578063397639ed146116a55780633fafa12714611600578063421c15e7146115e65780634e8b3d03146115715780636359a1c11461155857806370e5d2691461138c578063763c1783146112b15780637d41c8ed146111a157806386900c5814610fae5780638d17ea3c14610f8857806392ab91e314610f6b57806392b812aa14610f445780639a33e30014610e9f578063a054cbea14610e5a578063a68a22ea14610e3e578063b6632cb314610c74578063bec8e56c14610c31578063bfc12c0514610c14578063c5c145a114610bbb578063d56f2f8114610ba0578063d684b3c314610b38578063d721fe0214610a5a578063d94b20f514610a3d578063daf5d40214610a1b578063e526b5c9146109f9578063eaee5eaf146107f7578063ec7760c41461054b578063f03cb7ff14610436578063f321b30514610232578063f77c47911461020d5763fe993326146101dc575f80fd5b34610209576020600319360112610209576004355f5260056020526020600160405f200154604051908152f35b5f80fd5b34610209575f6003193601126102095760206001600160a01b035f5416604051908152f35b346102095760406003193601126102095761024b611eef565b60243567ffffffffffffffff81116102095761026b903690600401611f47565b909160ff600a541661040e576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016308114806103f6575b5f9015918261035a575b506010549060ff82169182610342575b5082610339575b5081610330575b50610308576102ee610306936102e6612480565b9336916123b5565b90604051926102fe6020856121ca565b5f8452612d7a565b005b7f752529d5000000000000000000000000000000000000000000000000000000005f5260045ffd5b905015846102d2565b159150856102cb565b6001600160a01b0391925060081c16321490866102c4565b60206103ab91610368612480565b6040517f8d17ea3c000000000000000000000000000000000000000000000000000000008152600481019190915233602482015292839190829081906044820190565b03915afa5f91816103c5575b50156102b4579050856102b4565b6103e891925060203d6020116103ef575b6103e081836121ca565b810190612270565b90876103b7565b503d6103d6565b506104096104026126d3565b329061290c565b6102aa565b7f64e0499a000000000000000000000000000000000000000000000000000000005f5260045ffd5b346102095761044436611f75565b9161044d612598565b506001600160a01b03831615610523576104689136916123b5565b60208151910120805f52600760205260ff60405f205416156104fb575f5260056020526001600160a01b0360405f2091165f5260205260405f2060ff600582015416156104d3576104bb6104cf916125e4565b604051918291602083526020830190612046565b0390f35b7f1d58d2de000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f9162df4b000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f27fd0962000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f6003193601126102095761056460015434101561220b565b5f54604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600960448201527f5265676973747261720000000000000000000000000000000000000000000000606482015233602482015290602090829060849082906001600160a01b03165afa9081156107ec575f916107cd575b5061072357335f52600360205260405f2060028154916001810161062761061582548096612288565b8095610622821515612295565b6122fa565b905501805490600182018092116106f65755610645346002546122fa565b6002555f80808084335af1610658612ab4565b5015610698576040519081525f60208201523460408201527fde56ffc0c60216b5973605759f98b72b1ffddde8c6aa70ea1228275844b5dcab60603392a2005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4574686572207472616e73666572206661696c656400000000000000000000006044820152fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b60a46040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f526567697374726172732f6c61756e636870616473206d6179206e6f7420626560448201527f20616c6c6f77656420746f207265766572736520616e7920616d6f756e74732060648201527f746865792073656e642e000000000000000000000000000000000000000000006084820152fd5b6107e6915060203d6020116103ef576103e081836121ca565b816105ec565b6040513d5f823e3d90fd5b346102095760806003193601126102095760043567ffffffffffffffff811161020957610828903690600401611f47565b610830611f05565b60443567ffffffffffffffff811161020957610850903690600401611f47565b91909360643567ffffffffffffffff811161020957610873903690600401611f47565b9390916108813687836123b5565b6020815191012095610891612696565b871480156109e9575b6108ac6108a5612480565b339061290c565b90806109e1575b156109945760ff600a541661040e576108d36108cd612480565b33612958565b1580610982575b61095a575b875f52600760205260ff60405f2054161561091e575b50602061091488888861090e896102e68f8b36916123b5565b92612d7a565b6040519015158152f35b92969594939192156104fb576020976109149761094b61094661090e966102e69536916123b5565b612c03565b509350978294959697506108f5565b7fd592fa10000000000000000000000000000000000000000000000000000000005f5260045ffd5b5061098e6108cd6126d3565b156108da565b8015806109c9575b156108df577f1209d2d2000000000000000000000000000000000000000000000000000000005f5260045ffd5b506109db336109d66126d3565b61290c565b1561099c565b5080156108b3565b506109f2612480565b871461089a565b34610209575f60031936011261020957602060ff600a54166040519015158152f35b34610209575f60031936011261020957602060ff601054166040519015158152f35b34610209575f600319360112610209576020600b54604051908152f35b34610209575f600319360112610209576040515f600c54610a7a816120ae565b8084529060018116908115610b145750600114610ab6575b6104cf83610aa2818503826121ca565b604051918291602083526020830190612003565b600c5f9081527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7939250905b808210610afa57509091508101602001610aa2610a92565b919260018160209254838588010152019101909291610ae2565b60ff191660208086019190915291151560051b84019091019150610aa29050610a92565b346102095761012060031936011261020957610b52611f05565b610b5a611f1b565b90610b63611f31565b9160e4356001600160a01b03811681036102095761010435918215158303610209576020946109149460c435926084359160443590600435612a3e565b34610209575f6003193601126102095760206040515f198152f35b34610209576020600319360112610209576001600160a01b03610bdc611eef565b165f52600360205260405f2080546104cf60026001840154930154604051938493846040919493926060820195825260208201520152565b34610209575f600319360112610209576020600f54604051908152f35b34610209575f6003193601126102095760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b34610209576020600319360112610209575f54604080517f127d532b000000000000000000000000000000000000000000000000000000008152600480820192909252600d60448201527f547265617375727941646d696e000000000000000000000000000000000000006064820152336024820152919035906001600160a01b0316602083608481845afa9283156107ec575f93610e1d575b508215610d50575b7f36a705a6c19db3ef2d8bf55ca55188c8499831bdf4fb8cd76fc1cf98b740bd27602083610d438661241b565b80600155604051908152a1005b604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600d60448201527f536d617274436f6e74726163740000000000000000000000000000000000000060648201523360248201529250602090839060849082905afa9081156107ec57610d436020927f36a705a6c19db3ef2d8bf55ca55188c8499831bdf4fb8cd76fc1cf98b740bd27945f91610e00575b5093505090610d16565b610e179150843d86116103ef576103e081836121ca565b85610df6565b610e3791935060203d6020116103ef576103e081836121ca565b9183610d0e565b34610209576020610914610e5136611fb8565b93929092612a00565b34610209575f6003193601126102095760206040516001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630148152f35b34610209575f600319360112610209576040515f600d54610ebf816120ae565b8084529060018116908115610b145750600114610ee6576104cf83610aa2818503826121ca565b600d5f9081527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5939250905b808210610f2a57509091508101602001610aa2610a92565b919260018160209254838588010152019101909291610f12565b34610209576040600319360112610209576020610914610f62611eef565b60243590612958565b34610209575f600319360112610209576020600154604051908152f35b34610209576040600319360112610209576020610914610fa6611f05565b60043561290c565b346102095760a06003193601126102095760043567ffffffffffffffff811161020957610fdf903690600401611f47565b90610fe8611f05565b9160443567ffffffffffffffff811161020957611009903690600401611f47565b909360643567ffffffffffffffff81116102095761102b903690600401611f47565b926084359561103b3687836123b5565b602081519101209564e8d4a51000881161117957611057612696565b87148015611169575b61106b6108a5612480565b9080611161575b156111195760ff600a541661040e5761108c6108cd612480565b1580611107575b61095a575b875f52600760205260ff60405f205416156110ce575b60206109148a8a8a8a8f8b6102e66110c8928d36916123b5565b9261329c565b9297969594939192156104fb57602098610914986110f76109466110c8966102e69536916123b5565b50935098829495969798506110ae565b506111136108cd6126d3565b15611093565b80158061114e575b15611098577f1209d2d2000000000000000000000000000000000000000000000000000000005f5260045ffd5b5061115b336109d66126d3565b15611121565b508015611072565b50611172612480565b8714611060565b7fba3e0179000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610209575f600319360112610209576008546111bd81612580565b906111cb60405192836121ca565b80825260208201908160085f527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee35f915b83831061128557848660405191829160208301906020845251809152604083019060408160051b85010192915f905b82821061123a57505050500390f35b91936020611275827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc060019597998495030186528851612003565b960192019201859493919261122b565b6001602081926040516112a38161129c81896120ff565b03826121ca565b8152019201920191906111fc565b34610209575f60031936011261020957600a5460ff8116611364576112d76108a56126d3565b906112e36108cd6126d3565b91158061135c575b6113345760ff196001911617600a5542600b5560405190151581524260208201527fa17d62523d9ec79d1a325025372506f5f81087175be21abe0a24da26b3cef8ab60403392a2005b7f82b42900000000000000000000000000000000000000000000000000000000005f5260045ffd5b5081156112eb565b7febb164e2000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610209576060600319360112610209576113a5611eef565b6044356001600160a01b038116809103610209576001600160a01b035f54166040517f127d532b0000000000000000000000000000000000000000000000000000000081526020818061143f336004830191909160408152600d60408201527f547265617375727941646d696e00000000000000000000000000000000000000606082015260206001600160a01b03608083019416910152565b0381855afa9081156107ec575f91611539575b508015611493575b611464915061241b565b5f5260046020526001600160a01b0360405f2091165f5260205260405f2061148f60243582546122fa565b9055005b50604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600d60448201527f536d617274436f6e747261637400000000000000000000000000000000000000606482015233602482015290602090829060849082905afa80156107ec57611464915f9161151a575b5061145a565b611533915060203d6020116103ef576103e081836121ca565b84611514565b611552915060203d6020116103ef576103e081836121ca565b84611452565b3461020957602061091461156b36611f75565b91612710565b346102095760406003193601126102095761158a611eef565b6001600160a01b0361159a611f05565b91165f5260046020526001600160a01b0360405f2091165f5260205260405f2080546104cf60026001840154930154604051938493846040919493926060820195825260208201520152565b34610209575f600319360112610209576020610914612660565b34610209575f600319360112610209576040515f600e54611620816120ae565b8084529060018116908115610b145750600114611647576104cf83610aa2818503826121ca565b600e5f9081527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd939250905b80821061168b57509091508101602001610aa2610a92565b919260018160209254838588010152019101909291611673565b346102095760406003193601126102095760043567ffffffffffffffff8111610209576116d6903690600401611f47565b906024359182159182158403610209576116f19136916123b5565b60208151910120805f52600760205260ff60405f205416156104fb575f52600560205260405f205f915f9160018101948554935b8481106118b757507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061177061175a87612580565b9661176860405198896121ca565b808852612580565b015f5b8181106118a05750505f925f5b85811061180a57866040518091602082016020835281518091526040830190602060408260051b8601019301915f905b8282106117bf57505050500390f35b919360206117fa827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc060019597998495030186528851612046565b96019201920185949391926117b0565b6001600160a01b0361181c828a612530565b90549060031b1c1682849061187f575b61183a575b50600101611780565b600191956001600160a01b0361187892165f528560205261185d60405f206125e4565b611867828b6125d0565b52611872818a6125d0565b50612572565b9490611831565b506001600160a01b0381165f528460205260ff600560405f2001541661182c565b6020906118ab612598565b82828a01015201611773565b836001600160a01b036118ca838a612530565b90549060031b1c1683916118fb575b506118e7575b600101611725565b946118f3600191612572565b9590506118df565b6001600160a01b039150165f528260205260ff600560405f20015416886118d9565b34610209575f6003193601126102095760206040516110d18152f35b34610209575f6003193601126102095760206109146124bd565b34610209575f6003193601126102095760206001600160a01b0360105460081c16604051908152f35b3461020957604060031936011261020957611995611eef565b5f54604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600d60448201527f547265617375727941646d696e00000000000000000000000000000000000000606482015233602482015291906001600160a01b0316602083608481845afa9283156107ec575f93611b00575b508215611a4e575b50611a356001600160a01b039261241b565b165f52600360205260405f2061148f60243582546122fa565b604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600d60448201527f536d617274436f6e74726163740000000000000000000000000000000000000060648201523360248201529250602090839060849082905afa9182156107ec576001600160a01b0392611a35915f91611ae1575b509250611a23565b611afa915060203d6020116103ef576103e081836121ca565b84611ad9565b611b1a91935060203d6020116103ef576103e081836121ca565b9183611a1b565b34610209576020610914611b3436611fb8565b939290926123eb565b34610209575f600319360112610209576020600254604051908152f35b3461020957611b6836611f75565b916001600160a01b0383161561052357611b839136916123b5565b60208151910120805f52600760205260ff60405f205416156104fb575f5260056020526001600160a01b0360405f2091165f52602052602060ff600560405f200154166040519015158152f35b346102095760e060031936011261020957611be9611f05565b611bf1611f1b565b611bf9611f31565b60c43590811515820361020957602093610914936084359160443590600435612307565b34610209575f60031936011261020957602060405164e8d4a510008152f35b602060031936011261020957611c50611eef565b611c5e60015434101561220b565b5f54604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600960448201527f5265676973747261720000000000000000000000000000000000000000000000606482015233602482015290602090829060849082906001600160a01b03165afa9081156107ec575f91611ed0575b50611e4c576001600160a01b0316805f52600460205260405f206001600160a01b0333165f5260205260405f2090600282549260018101611d39611d2c82548097612288565b8096610622821515612295565b905501805490600182018092116106f65755611d57346002546122fa565b600255611dba5f8060405160208101907fa9059cbb00000000000000000000000000000000000000000000000000000000825233602482015286604482015260448152611da56064826121ca565b519082865af1611db3612ab4565b908361379b565b8051908115159182611e31575b5050611e065760405191825260208201523460408201527fde56ffc0c60216b5973605759f98b72b1ffddde8c6aa70ea1228275844b5dcab60603392a2005b7f5274afe7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b611e449250602080918301019101612270565b158380611dc7565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f526567697374726172732f6c61756e636870616473206d6179206e6f7420726560448201527f766572736520616e7920616d6f756e747320746865792073656e642e000000006064820152fd5b611ee9915060203d6020116103ef576103e081836121ca565b82611ce6565b600435906001600160a01b038216820361020957565b602435906001600160a01b038216820361020957565b606435906001600160a01b038216820361020957565b60a435906001600160a01b038216820361020957565b9181601f840112156102095782359167ffffffffffffffff8311610209576020838186019501011161020957565b6040600319820112610209576004359067ffffffffffffffff821161020957611fa091600401611f47565b90916024356001600160a01b03811681036102095790565b60031960a091011261020957600435906024356001600160a01b03811681036102095790604435906064356001600160a01b0381168103610209579060843580151581036102095790565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602080948051918291828752018686015e5f8582860101520116010190565b9060c080612072612060855160e0865260e0860190612003565b60208601518582036020870152612003565b936001600160a01b036040820151166040850152606081015160608501526080810151608085015260a0810151151560a0850152015191015290565b90600182811c921680156120f5575b60208310146120c857565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b91607f16916120bd565b5f929181549161210e836120ae565b8083529260018116908115612163575060011461212a57505050565b5f9081526020812093945091925b838310612149575060209250010190565b600181602092949394548385870101520191019190612138565b9050602094955060ff1991509291921683830152151560051b010190565b60e0810190811067ffffffffffffffff82111761219d57604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761219d57604052565b1561221257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e73756666696369656e742061646d696e20666565000000000000000000006044820152fd5b90816020910312610209575180151581036102095790565b919082039182116106f657565b1561229c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f7468696e6720746f20726566756e640000000000000000000000000000006044820152fd5b919082018092116106f657565b91951561234a576123179161290c565b9384612337575b50508261232a57505090565b612334925061290c565b90565b61234292945061290c565b915f8061231e565b6123539161290c565b938415612368575b5050821561232a57505090565b61237392945061290c565b915f8061235b565b67ffffffffffffffff811161219d57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9291926123c18261237b565b916123cf60405193846121ca565b829481845281830111610209578281602093845f960137010152565b919315612406576123fb9161290c565b918261232a57505090565b61240f9161290c565b91821561232a57505090565b1561242257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f556e617574686f72697a656420616363657373000000000000000000000000006044820152fd5b600d60206040516124926040826121ca565b828152017f536d617274436f6e74726163740000000000000000000000000000000000000081522090565b60ff600a541661040e576124d26108cd612480565b156113345760105460ff811661252b577fffffffffffffffffffffff000000000000000000000000000000000000000000163260081b74ffffffffffffffffffffffffffffffffffffffff001617600190811760105590565b505f90565b8054821015612545575f5260205f2001905f90565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f1981146106f65760010190565b67ffffffffffffffff811161219d5760051b60200190565b604051906125a582612181565b5f60c08360608152606060208201528260408201528260608201528260808201528260a08201520152565b80518210156125455760209160051b010190565b906040516125f181612181565b60c0600682946040516126088161129c81856120ff565b845260405161261e8161129c81600186016120ff565b60208501526001600160a01b036002820154166040850152600381015460608501526004810154608085015260ff600582015416151560a08501520154910152565b60105460ff81161561252b577fffffffffffffffffffffff00000000000000000000000000000000000000000016601055600190565b601360206040516126a86040826121ca565b828152017f504c4154464f524d5f434f4e54524f4c4c45520000000000000000000000000081522090565b600560206040516126e56040826121ca565b828152017f537570657200000000000000000000000000000000000000000000000000000081522090565b61271b9136916123b5565b602081519101209061272b612696565b82149081156128fa575b60ff600a5416806128f3575b61040e576001600160a01b031690811561052357825f52600760205260ff60405f205416156104fb57806128e1575b156128aa576127806108cd612480565b1580612898575b61095a575b815f52600560205260405f2090805f528160205260ff600560405f200154161561289157805f5281602052600560405f200160ff1981541690557f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db9360406128748151916127f981846121ca565b60068084527f52656d6f766500000000000000000000000000000000000000000000000000006020808601919091525f8781529790529581902095860154815160c0808252919790946001926128669183916128589190890190612003565b9087820360208901526120ff565b9285840390860152016120ff565b934260608301525f608083015260a08201528033940390a4600190565b5050505f90565b506128a46108cd6126d3565b15612787565b6128b56108a56126d3565b61278c577f1209d2d2000000000000000000000000000000000000000000000000000000005f5260045ffd5b506128ed6108a5612480565b15612770565b5081612741565b9050612904612480565b821490612735565b6001600160a01b0382161561052357805f52600760205260ff60405f205416156104fb575f5260056020526001600160a01b0360405f2091165f5260205260ff600560405f2001541690565b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169130831461232a576040517f8d17ea3c00000000000000000000000000000000000000000000000000000000815260048101919091526001600160a01b0391909116602482015290602090829060449082905afa9081156107ec575f916129e7575090565b612334915060203d6020116103ef576103e081836121ca565b919315612a2957612a109161290c565b9182612a1b57505090565b612a25925061290c565b1590565b612a329161290c565b918215612a1b57505090565b919715612a7b57612a4e9161290c565b9586612a68575b5050846123375750508261232a57505090565b612a7392965061290c565b935f80612a55565b612a849161290c565b958615612aa1575b50508415612368575050821561232a57505090565b612aac92965061290c565b935f80612a8c565b3d15612ade573d90612ac58261237b565b91612ad360405193846121ca565b82523d5f602084013e565b606090565b919091825167ffffffffffffffff811161219d57612b0182546120ae565b601f8111612bbe575b506020601f8211600114612b4257819293945f92612b37575b50505f198260011b9260031b1c1916179055565b015190505f80612b23565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0821690835f52805f20915f5b818110612ba657509583600195969710612b8e575b505050811b019055565b01515f1960f88460031b161c191690555f8080612b84565b9192602060018192868b015181550194019201612b6f565b825f5260205f20601f830160051c81019160208410612bf9575b601f0160051c01905b818110612bee5750612b0a565b5f8155600101612be1565b9091508190612bd8565b5f9060405160ff825191602081818601948086835e81016006815203019020541615612c2e57505090565b908092505160208183209282604051938492835e81016006815203019020600160ff19825416179055805f52600760205260405f20600160ff198254161790555f526009602052612c828160405f20612ae3565b600854906801000000000000000082101561219d57600182016008556008548210156125455760085f52612cd7917ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee301612ae3565b600190565b60405190612ceb6040836121ca565b600c82527f5343206e6f7420746f6b656e00000000000000000000000000000000000000006020830152565b6020818303126102095780519067ffffffffffffffff8211610209570181601f8201121561020957805190612d4b8261237b565b92612d5960405194856121ca565b8284526020838301011161020957815f9260208093018386015e8301015290565b925f6001600160a01b0383169283156105235784511561320a575b825115613107575b50845f52600560205260405f20835f52806020526001600160a01b03600260405f20015416612faa57600190604051612dd581612181565b868152600686612e886020840188815260408501838152606086014381526080870191428352612e2d60a08901948b865260c08a01975f1989525f528a602052612e2460405f209a518b612ae3565b518b8a01612ae3565b6001600160a01b03600289019151167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055516003870155516004860155511515600585019060ff60ff1983541691151516179055565b519101550180549168010000000000000000831015612f7d575091612ed7827f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db93946001612f5d95018155612530565b81549060031b906001600160a01b0387831b921b1916179055612f4f60405195612f026040886121ca565b600387527f41646400000000000000000000000000000000000000000000000000000000006020880152612f416040519760c0895260c0890190612003565b908782036020890152612003565b908582036040870152612003565b92426060820152600160808201525f1960a08201528033940390a4600190565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526041600452fd5b949293919050835f528460205260ff600560405f200154165f14613039575050505f526020525f19600660405f200154148080613031575b811561301a575b50612ff2575f90565b7f59e82fe0000000000000000000000000000000000000000000000000000000005f5260045ffd5b90501580613029575b5f612fe9565b506001613023565b5f9150612fe2565b612f5d907f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db9392949395845f52806020526130768660405f20612ae3565b845f528060205261308d82600160405f2001612ae3565b5f858152602091825260409081902043600382015542600482015560058101805460ff191660011790555f196006909101555160c0808252600a908201527f526561637469766174650000000000000000000000000000000000000000000060e082015261010091810182905295612f4f91870190612003565b9091503b156131cc576040517f95d89b410000000000000000000000000000000000000000000000000000000081525f81600481865afa5f91816131a8575b5061315c5750613154612cdc565b905b5f612d9d565b80511561316a575b90613156565b506040516131796040826121ca565b601281527f5343206e6f20746f6b656e2073796d626f6c00000000000000000000000000006020820152613164565b6131c59192503d805f833e6131bd81836121ca565b810190612d17565b905f613146565b6040516131da6040826121ca565b600d81527f77616c6c6574206e6f7420534300000000000000000000000000000000000000602082015290613156565b9350833b15613294576040517f06fdde030000000000000000000000000000000000000000000000000000000081525f81600481875afa5f9181613278575b5061325d5750613257612cdc565b93612d95565b80511561326a5793612d95565b50613273612cdc565b613257565b61328d9192503d805f833e6131bd81836121ca565b905f613249565b613257612cdc565b939290916001600160a01b03831692831561052357815115613709575b82511561360e575b50845f52600560205260405f20835f52806020526001600160a01b03600260405f2001541661343a576001906040516132f981612181565b8381526006876133488860208501898152604086018281526060870190438252612e2d608089019342855260a08a01958c875260c08b019889525f528a602052612e2460405f209a518b612ae3565b5191015501918254906801000000000000000082101561219d57613396827f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db9395600161341c95018155612530565b81549060031b906001600160a01b0388831b921b191617905561340e604051936133c16040866121ca565b600385527f416464000000000000000000000000000000000000000000000000000000000060208601526134006040519560c0875260c0870190612003565b908582036020870152612003565b908382036040850152612003565b934260608301526001608083015260a08201528033940390a4600190565b835f528060205260ff600560405f200154165f1461354557835f5280602052600660405f2001545f1981148080613539575b8115613520575b50612ff257855f198114159182613515575b5050613495575050505050505f90565b7f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db939261341c91855f5260205285600660405f20015561340e6040519360c08552600b60c08601527f55706461746556616c756500000000000000000000000000000000000000000060e08601526101006020860152610100850190612003565b14159050855f613485565b9050158061352f575b5f613473565b505f198614613529565b5f19881415915061346c565b7f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db939261341c91855f528060205261357f8460405f20612ae3565b855f528060205261359682600160405f2001612ae3565b5f868152602091825260409081902043600382015542600482015560058101805460ff191660011790556006018890555160c0808252600a908201527f526561637469766174650000000000000000000000000000000000000000000060e08201526101009181018290529361340e91850190612003565b9091503b156136cb576040517f95d89b410000000000000000000000000000000000000000000000000000000081525f81600481865afa5f91816136af575b50613663575061365b612cdc565b905b5f6132c1565b805115613671575b9061365d565b506040516136806040826121ca565b601281527f5343206e6f20746f6b656e2073796d626f6c0000000000000000000000000000602082015261366b565b6136c49192503d805f833e6131bd81836121ca565b905f61364d565b6040516136d96040826121ca565b600d81527f77616c6c6574206e6f742053430000000000000000000000000000000000000060208201529061365d565b9050803b15613793576040517f06fdde030000000000000000000000000000000000000000000000000000000081525f81600481875afa5f9181613777575b5061375c5750613756612cdc565b906132b9565b80511561376957906132b9565b50613772612cdc565b613756565b61378c9192503d805f833e6131bd81836121ca565b905f613748565b613756612cdc565b906137d857508051156137b057805190602001fd5b7f1425ea42000000000000000000000000000000000000000000000000000000005f5260045ffd5b8151158061381e575b6137e9575090565b6001600160a01b03907f9996b315000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b50803b156137e156fea26469706673582212201e176cd272a5b1358b41332457bd6236ad6011e71e6cabcc57048643f6de6dbc64736f6c634300081e0033df6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c771367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db93000000000000000000000000ead140af0ec3de7d47c18efc17b1b1e479f2326c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000e55532046696e74656368204c4c43000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b55532046696e74656368204c4c43204e657720596f726b205553410000000000000000000000000000000000000000000000000000000000000000000000001f457175697479204d696e7420506c6174666f726d20616e64204d6f64656c7300000000000000000000000000000000000000000000000000000000000000000856342e332e302e35000000000000000000000000000000000000000000000000

Deployed Bytecode

0x60806040526004361015610011575f80fd5b5f3560e01c806301d7a0a814611c3c578063063bde2414611c1d57806307f1ef9e14611bd0578063127d532b14611b5a57806315a0d6b714611b3d5780631711e9a014611b215780631ea5283e1461197c57806328f2a80a146119535780632cbc35e41461193957806338b903331461191d578063397639ed146116a55780633fafa12714611600578063421c15e7146115e65780634e8b3d03146115715780636359a1c11461155857806370e5d2691461138c578063763c1783146112b15780637d41c8ed146111a157806386900c5814610fae5780638d17ea3c14610f8857806392ab91e314610f6b57806392b812aa14610f445780639a33e30014610e9f578063a054cbea14610e5a578063a68a22ea14610e3e578063b6632cb314610c74578063bec8e56c14610c31578063bfc12c0514610c14578063c5c145a114610bbb578063d56f2f8114610ba0578063d684b3c314610b38578063d721fe0214610a5a578063d94b20f514610a3d578063daf5d40214610a1b578063e526b5c9146109f9578063eaee5eaf146107f7578063ec7760c41461054b578063f03cb7ff14610436578063f321b30514610232578063f77c47911461020d5763fe993326146101dc575f80fd5b34610209576020600319360112610209576004355f5260056020526020600160405f200154604051908152f35b5f80fd5b34610209575f6003193601126102095760206001600160a01b035f5416604051908152f35b346102095760406003193601126102095761024b611eef565b60243567ffffffffffffffff81116102095761026b903690600401611f47565b909160ff600a541661040e576001600160a01b037f0000000000000000000000004a2457948cf69f6747af1a7d5e3f84707bf1ab8416308114806103f6575b5f9015918261035a575b506010549060ff82169182610342575b5082610339575b5081610330575b50610308576102ee610306936102e6612480565b9336916123b5565b90604051926102fe6020856121ca565b5f8452612d7a565b005b7f752529d5000000000000000000000000000000000000000000000000000000005f5260045ffd5b905015846102d2565b159150856102cb565b6001600160a01b0391925060081c16321490866102c4565b60206103ab91610368612480565b6040517f8d17ea3c000000000000000000000000000000000000000000000000000000008152600481019190915233602482015292839190829081906044820190565b03915afa5f91816103c5575b50156102b4579050856102b4565b6103e891925060203d6020116103ef575b6103e081836121ca565b810190612270565b90876103b7565b503d6103d6565b506104096104026126d3565b329061290c565b6102aa565b7f64e0499a000000000000000000000000000000000000000000000000000000005f5260045ffd5b346102095761044436611f75565b9161044d612598565b506001600160a01b03831615610523576104689136916123b5565b60208151910120805f52600760205260ff60405f205416156104fb575f5260056020526001600160a01b0360405f2091165f5260205260405f2060ff600582015416156104d3576104bb6104cf916125e4565b604051918291602083526020830190612046565b0390f35b7f1d58d2de000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f9162df4b000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f27fd0962000000000000000000000000000000000000000000000000000000005f5260045ffd5b5f6003193601126102095761056460015434101561220b565b5f54604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600960448201527f5265676973747261720000000000000000000000000000000000000000000000606482015233602482015290602090829060849082906001600160a01b03165afa9081156107ec575f916107cd575b5061072357335f52600360205260405f2060028154916001810161062761061582548096612288565b8095610622821515612295565b6122fa565b905501805490600182018092116106f65755610645346002546122fa565b6002555f80808084335af1610658612ab4565b5015610698576040519081525f60208201523460408201527fde56ffc0c60216b5973605759f98b72b1ffddde8c6aa70ea1228275844b5dcab60603392a2005b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4574686572207472616e73666572206661696c656400000000000000000000006044820152fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b60a46040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f526567697374726172732f6c61756e636870616473206d6179206e6f7420626560448201527f20616c6c6f77656420746f207265766572736520616e7920616d6f756e74732060648201527f746865792073656e642e000000000000000000000000000000000000000000006084820152fd5b6107e6915060203d6020116103ef576103e081836121ca565b816105ec565b6040513d5f823e3d90fd5b346102095760806003193601126102095760043567ffffffffffffffff811161020957610828903690600401611f47565b610830611f05565b60443567ffffffffffffffff811161020957610850903690600401611f47565b91909360643567ffffffffffffffff811161020957610873903690600401611f47565b9390916108813687836123b5565b6020815191012095610891612696565b871480156109e9575b6108ac6108a5612480565b339061290c565b90806109e1575b156109945760ff600a541661040e576108d36108cd612480565b33612958565b1580610982575b61095a575b875f52600760205260ff60405f2054161561091e575b50602061091488888861090e896102e68f8b36916123b5565b92612d7a565b6040519015158152f35b92969594939192156104fb576020976109149761094b61094661090e966102e69536916123b5565b612c03565b509350978294959697506108f5565b7fd592fa10000000000000000000000000000000000000000000000000000000005f5260045ffd5b5061098e6108cd6126d3565b156108da565b8015806109c9575b156108df577f1209d2d2000000000000000000000000000000000000000000000000000000005f5260045ffd5b506109db336109d66126d3565b61290c565b1561099c565b5080156108b3565b506109f2612480565b871461089a565b34610209575f60031936011261020957602060ff600a54166040519015158152f35b34610209575f60031936011261020957602060ff601054166040519015158152f35b34610209575f600319360112610209576020600b54604051908152f35b34610209575f600319360112610209576040515f600c54610a7a816120ae565b8084529060018116908115610b145750600114610ab6575b6104cf83610aa2818503826121ca565b604051918291602083526020830190612003565b600c5f9081527fdf6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7939250905b808210610afa57509091508101602001610aa2610a92565b919260018160209254838588010152019101909291610ae2565b60ff191660208086019190915291151560051b84019091019150610aa29050610a92565b346102095761012060031936011261020957610b52611f05565b610b5a611f1b565b90610b63611f31565b9160e4356001600160a01b03811681036102095761010435918215158303610209576020946109149460c435926084359160443590600435612a3e565b34610209575f6003193601126102095760206040515f198152f35b34610209576020600319360112610209576001600160a01b03610bdc611eef565b165f52600360205260405f2080546104cf60026001840154930154604051938493846040919493926060820195825260208201520152565b34610209575f600319360112610209576020600f54604051908152f35b34610209575f6003193601126102095760206040516001600160a01b037f0000000000000000000000004a2457948cf69f6747af1a7d5e3f84707bf1ab84168152f35b34610209576020600319360112610209575f54604080517f127d532b000000000000000000000000000000000000000000000000000000008152600480820192909252600d60448201527f547265617375727941646d696e000000000000000000000000000000000000006064820152336024820152919035906001600160a01b0316602083608481845afa9283156107ec575f93610e1d575b508215610d50575b7f36a705a6c19db3ef2d8bf55ca55188c8499831bdf4fb8cd76fc1cf98b740bd27602083610d438661241b565b80600155604051908152a1005b604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600d60448201527f536d617274436f6e74726163740000000000000000000000000000000000000060648201523360248201529250602090839060849082905afa9081156107ec57610d436020927f36a705a6c19db3ef2d8bf55ca55188c8499831bdf4fb8cd76fc1cf98b740bd27945f91610e00575b5093505090610d16565b610e179150843d86116103ef576103e081836121ca565b85610df6565b610e3791935060203d6020116103ef576103e081836121ca565b9183610d0e565b34610209576020610914610e5136611fb8565b93929092612a00565b34610209575f6003193601126102095760206040516001600160a01b037f0000000000000000000000004a2457948cf69f6747af1a7d5e3f84707bf1ab841630148152f35b34610209575f600319360112610209576040515f600d54610ebf816120ae565b8084529060018116908115610b145750600114610ee6576104cf83610aa2818503826121ca565b600d5f9081527fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5939250905b808210610f2a57509091508101602001610aa2610a92565b919260018160209254838588010152019101909291610f12565b34610209576040600319360112610209576020610914610f62611eef565b60243590612958565b34610209575f600319360112610209576020600154604051908152f35b34610209576040600319360112610209576020610914610fa6611f05565b60043561290c565b346102095760a06003193601126102095760043567ffffffffffffffff811161020957610fdf903690600401611f47565b90610fe8611f05565b9160443567ffffffffffffffff811161020957611009903690600401611f47565b909360643567ffffffffffffffff81116102095761102b903690600401611f47565b926084359561103b3687836123b5565b602081519101209564e8d4a51000881161117957611057612696565b87148015611169575b61106b6108a5612480565b9080611161575b156111195760ff600a541661040e5761108c6108cd612480565b1580611107575b61095a575b875f52600760205260ff60405f205416156110ce575b60206109148a8a8a8a8f8b6102e66110c8928d36916123b5565b9261329c565b9297969594939192156104fb57602098610914986110f76109466110c8966102e69536916123b5565b50935098829495969798506110ae565b506111136108cd6126d3565b15611093565b80158061114e575b15611098577f1209d2d2000000000000000000000000000000000000000000000000000000005f5260045ffd5b5061115b336109d66126d3565b15611121565b508015611072565b50611172612480565b8714611060565b7fba3e0179000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610209575f600319360112610209576008546111bd81612580565b906111cb60405192836121ca565b80825260208201908160085f527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee35f915b83831061128557848660405191829160208301906020845251809152604083019060408160051b85010192915f905b82821061123a57505050500390f35b91936020611275827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc060019597998495030186528851612003565b960192019201859493919261122b565b6001602081926040516112a38161129c81896120ff565b03826121ca565b8152019201920191906111fc565b34610209575f60031936011261020957600a5460ff8116611364576112d76108a56126d3565b906112e36108cd6126d3565b91158061135c575b6113345760ff196001911617600a5542600b5560405190151581524260208201527fa17d62523d9ec79d1a325025372506f5f81087175be21abe0a24da26b3cef8ab60403392a2005b7f82b42900000000000000000000000000000000000000000000000000000000005f5260045ffd5b5081156112eb565b7febb164e2000000000000000000000000000000000000000000000000000000005f5260045ffd5b34610209576060600319360112610209576113a5611eef565b6044356001600160a01b038116809103610209576001600160a01b035f54166040517f127d532b0000000000000000000000000000000000000000000000000000000081526020818061143f336004830191909160408152600d60408201527f547265617375727941646d696e00000000000000000000000000000000000000606082015260206001600160a01b03608083019416910152565b0381855afa9081156107ec575f91611539575b508015611493575b611464915061241b565b5f5260046020526001600160a01b0360405f2091165f5260205260405f2061148f60243582546122fa565b9055005b50604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600d60448201527f536d617274436f6e747261637400000000000000000000000000000000000000606482015233602482015290602090829060849082905afa80156107ec57611464915f9161151a575b5061145a565b611533915060203d6020116103ef576103e081836121ca565b84611514565b611552915060203d6020116103ef576103e081836121ca565b84611452565b3461020957602061091461156b36611f75565b91612710565b346102095760406003193601126102095761158a611eef565b6001600160a01b0361159a611f05565b91165f5260046020526001600160a01b0360405f2091165f5260205260405f2080546104cf60026001840154930154604051938493846040919493926060820195825260208201520152565b34610209575f600319360112610209576020610914612660565b34610209575f600319360112610209576040515f600e54611620816120ae565b8084529060018116908115610b145750600114611647576104cf83610aa2818503826121ca565b600e5f9081527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd939250905b80821061168b57509091508101602001610aa2610a92565b919260018160209254838588010152019101909291611673565b346102095760406003193601126102095760043567ffffffffffffffff8111610209576116d6903690600401611f47565b906024359182159182158403610209576116f19136916123b5565b60208151910120805f52600760205260ff60405f205416156104fb575f52600560205260405f205f915f9160018101948554935b8481106118b757507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061177061175a87612580565b9661176860405198896121ca565b808852612580565b015f5b8181106118a05750505f925f5b85811061180a57866040518091602082016020835281518091526040830190602060408260051b8601019301915f905b8282106117bf57505050500390f35b919360206117fa827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc060019597998495030186528851612046565b96019201920185949391926117b0565b6001600160a01b0361181c828a612530565b90549060031b1c1682849061187f575b61183a575b50600101611780565b600191956001600160a01b0361187892165f528560205261185d60405f206125e4565b611867828b6125d0565b52611872818a6125d0565b50612572565b9490611831565b506001600160a01b0381165f528460205260ff600560405f2001541661182c565b6020906118ab612598565b82828a01015201611773565b836001600160a01b036118ca838a612530565b90549060031b1c1683916118fb575b506118e7575b600101611725565b946118f3600191612572565b9590506118df565b6001600160a01b039150165f528260205260ff600560405f20015416886118d9565b34610209575f6003193601126102095760206040516110d18152f35b34610209575f6003193601126102095760206109146124bd565b34610209575f6003193601126102095760206001600160a01b0360105460081c16604051908152f35b3461020957604060031936011261020957611995611eef565b5f54604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600d60448201527f547265617375727941646d696e00000000000000000000000000000000000000606482015233602482015291906001600160a01b0316602083608481845afa9283156107ec575f93611b00575b508215611a4e575b50611a356001600160a01b039261241b565b165f52600360205260405f2061148f60243582546122fa565b604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600d60448201527f536d617274436f6e74726163740000000000000000000000000000000000000060648201523360248201529250602090839060849082905afa9182156107ec576001600160a01b0392611a35915f91611ae1575b509250611a23565b611afa915060203d6020116103ef576103e081836121ca565b84611ad9565b611b1a91935060203d6020116103ef576103e081836121ca565b9183611a1b565b34610209576020610914611b3436611fb8565b939290926123eb565b34610209575f600319360112610209576020600254604051908152f35b3461020957611b6836611f75565b916001600160a01b0383161561052357611b839136916123b5565b60208151910120805f52600760205260ff60405f205416156104fb575f5260056020526001600160a01b0360405f2091165f52602052602060ff600560405f200154166040519015158152f35b346102095760e060031936011261020957611be9611f05565b611bf1611f1b565b611bf9611f31565b60c43590811515820361020957602093610914936084359160443590600435612307565b34610209575f60031936011261020957602060405164e8d4a510008152f35b602060031936011261020957611c50611eef565b611c5e60015434101561220b565b5f54604080517f127d532b0000000000000000000000000000000000000000000000000000000081526004810191909152600960448201527f5265676973747261720000000000000000000000000000000000000000000000606482015233602482015290602090829060849082906001600160a01b03165afa9081156107ec575f91611ed0575b50611e4c576001600160a01b0316805f52600460205260405f206001600160a01b0333165f5260205260405f2090600282549260018101611d39611d2c82548097612288565b8096610622821515612295565b905501805490600182018092116106f65755611d57346002546122fa565b600255611dba5f8060405160208101907fa9059cbb00000000000000000000000000000000000000000000000000000000825233602482015286604482015260448152611da56064826121ca565b519082865af1611db3612ab4565b908361379b565b8051908115159182611e31575b5050611e065760405191825260208201523460408201527fde56ffc0c60216b5973605759f98b72b1ffddde8c6aa70ea1228275844b5dcab60603392a2005b7f5274afe7000000000000000000000000000000000000000000000000000000005f5260045260245ffd5b611e449250602080918301019101612270565b158380611dc7565b60846040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f526567697374726172732f6c61756e636870616473206d6179206e6f7420726560448201527f766572736520616e7920616d6f756e747320746865792073656e642e000000006064820152fd5b611ee9915060203d6020116103ef576103e081836121ca565b82611ce6565b600435906001600160a01b038216820361020957565b602435906001600160a01b038216820361020957565b606435906001600160a01b038216820361020957565b60a435906001600160a01b038216820361020957565b9181601f840112156102095782359167ffffffffffffffff8311610209576020838186019501011161020957565b6040600319820112610209576004359067ffffffffffffffff821161020957611fa091600401611f47565b90916024356001600160a01b03811681036102095790565b60031960a091011261020957600435906024356001600160a01b03811681036102095790604435906064356001600160a01b0381168103610209579060843580151581036102095790565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602080948051918291828752018686015e5f8582860101520116010190565b9060c080612072612060855160e0865260e0860190612003565b60208601518582036020870152612003565b936001600160a01b036040820151166040850152606081015160608501526080810151608085015260a0810151151560a0850152015191015290565b90600182811c921680156120f5575b60208310146120c857565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b91607f16916120bd565b5f929181549161210e836120ae565b8083529260018116908115612163575060011461212a57505050565b5f9081526020812093945091925b838310612149575060209250010190565b600181602092949394548385870101520191019190612138565b9050602094955060ff1991509291921683830152151560051b010190565b60e0810190811067ffffffffffffffff82111761219d57604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff82111761219d57604052565b1561221257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f496e73756666696369656e742061646d696e20666565000000000000000000006044820152fd5b90816020910312610209575180151581036102095790565b919082039182116106f657565b1561229c57565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4e6f7468696e6720746f20726566756e640000000000000000000000000000006044820152fd5b919082018092116106f657565b91951561234a576123179161290c565b9384612337575b50508261232a57505090565b612334925061290c565b90565b61234292945061290c565b915f8061231e565b6123539161290c565b938415612368575b5050821561232a57505090565b61237392945061290c565b915f8061235b565b67ffffffffffffffff811161219d57601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b9291926123c18261237b565b916123cf60405193846121ca565b829481845281830111610209578281602093845f960137010152565b919315612406576123fb9161290c565b918261232a57505090565b61240f9161290c565b91821561232a57505090565b1561242257565b60646040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f556e617574686f72697a656420616363657373000000000000000000000000006044820152fd5b600d60206040516124926040826121ca565b828152017f536d617274436f6e74726163740000000000000000000000000000000000000081522090565b60ff600a541661040e576124d26108cd612480565b156113345760105460ff811661252b577fffffffffffffffffffffff000000000000000000000000000000000000000000163260081b74ffffffffffffffffffffffffffffffffffffffff001617600190811760105590565b505f90565b8054821015612545575f5260205f2001905f90565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f1981146106f65760010190565b67ffffffffffffffff811161219d5760051b60200190565b604051906125a582612181565b5f60c08360608152606060208201528260408201528260608201528260808201528260a08201520152565b80518210156125455760209160051b010190565b906040516125f181612181565b60c0600682946040516126088161129c81856120ff565b845260405161261e8161129c81600186016120ff565b60208501526001600160a01b036002820154166040850152600381015460608501526004810154608085015260ff600582015416151560a08501520154910152565b60105460ff81161561252b577fffffffffffffffffffffff00000000000000000000000000000000000000000016601055600190565b601360206040516126a86040826121ca565b828152017f504c4154464f524d5f434f4e54524f4c4c45520000000000000000000000000081522090565b600560206040516126e56040826121ca565b828152017f537570657200000000000000000000000000000000000000000000000000000081522090565b61271b9136916123b5565b602081519101209061272b612696565b82149081156128fa575b60ff600a5416806128f3575b61040e576001600160a01b031690811561052357825f52600760205260ff60405f205416156104fb57806128e1575b156128aa576127806108cd612480565b1580612898575b61095a575b815f52600560205260405f2090805f528160205260ff600560405f200154161561289157805f5281602052600560405f200160ff1981541690557f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db9360406128748151916127f981846121ca565b60068084527f52656d6f766500000000000000000000000000000000000000000000000000006020808601919091525f8781529790529581902095860154815160c0808252919790946001926128669183916128589190890190612003565b9087820360208901526120ff565b9285840390860152016120ff565b934260608301525f608083015260a08201528033940390a4600190565b5050505f90565b506128a46108cd6126d3565b15612787565b6128b56108a56126d3565b61278c577f1209d2d2000000000000000000000000000000000000000000000000000000005f5260045ffd5b506128ed6108a5612480565b15612770565b5081612741565b9050612904612480565b821490612735565b6001600160a01b0382161561052357805f52600760205260ff60405f205416156104fb575f5260056020526001600160a01b0360405f2091165f5260205260ff600560405f2001541690565b6001600160a01b037f0000000000000000000000004a2457948cf69f6747af1a7d5e3f84707bf1ab84169130831461232a576040517f8d17ea3c00000000000000000000000000000000000000000000000000000000815260048101919091526001600160a01b0391909116602482015290602090829060449082905afa9081156107ec575f916129e7575090565b612334915060203d6020116103ef576103e081836121ca565b919315612a2957612a109161290c565b9182612a1b57505090565b612a25925061290c565b1590565b612a329161290c565b918215612a1b57505090565b919715612a7b57612a4e9161290c565b9586612a68575b5050846123375750508261232a57505090565b612a7392965061290c565b935f80612a55565b612a849161290c565b958615612aa1575b50508415612368575050821561232a57505090565b612aac92965061290c565b935f80612a8c565b3d15612ade573d90612ac58261237b565b91612ad360405193846121ca565b82523d5f602084013e565b606090565b919091825167ffffffffffffffff811161219d57612b0182546120ae565b601f8111612bbe575b506020601f8211600114612b4257819293945f92612b37575b50505f198260011b9260031b1c1916179055565b015190505f80612b23565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0821690835f52805f20915f5b818110612ba657509583600195969710612b8e575b505050811b019055565b01515f1960f88460031b161c191690555f8080612b84565b9192602060018192868b015181550194019201612b6f565b825f5260205f20601f830160051c81019160208410612bf9575b601f0160051c01905b818110612bee5750612b0a565b5f8155600101612be1565b9091508190612bd8565b5f9060405160ff825191602081818601948086835e81016006815203019020541615612c2e57505090565b908092505160208183209282604051938492835e81016006815203019020600160ff19825416179055805f52600760205260405f20600160ff198254161790555f526009602052612c828160405f20612ae3565b600854906801000000000000000082101561219d57600182016008556008548210156125455760085f52612cd7917ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee301612ae3565b600190565b60405190612ceb6040836121ca565b600c82527f5343206e6f7420746f6b656e00000000000000000000000000000000000000006020830152565b6020818303126102095780519067ffffffffffffffff8211610209570181601f8201121561020957805190612d4b8261237b565b92612d5960405194856121ca565b8284526020838301011161020957815f9260208093018386015e8301015290565b925f6001600160a01b0383169283156105235784511561320a575b825115613107575b50845f52600560205260405f20835f52806020526001600160a01b03600260405f20015416612faa57600190604051612dd581612181565b868152600686612e886020840188815260408501838152606086014381526080870191428352612e2d60a08901948b865260c08a01975f1989525f528a602052612e2460405f209a518b612ae3565b518b8a01612ae3565b6001600160a01b03600289019151167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055516003870155516004860155511515600585019060ff60ff1983541691151516179055565b519101550180549168010000000000000000831015612f7d575091612ed7827f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db93946001612f5d95018155612530565b81549060031b906001600160a01b0387831b921b1916179055612f4f60405195612f026040886121ca565b600387527f41646400000000000000000000000000000000000000000000000000000000006020880152612f416040519760c0895260c0890190612003565b908782036020890152612003565b908582036040870152612003565b92426060820152600160808201525f1960a08201528033940390a4600190565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526041600452fd5b949293919050835f528460205260ff600560405f200154165f14613039575050505f526020525f19600660405f200154148080613031575b811561301a575b50612ff2575f90565b7f59e82fe0000000000000000000000000000000000000000000000000000000005f5260045ffd5b90501580613029575b5f612fe9565b506001613023565b5f9150612fe2565b612f5d907f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db9392949395845f52806020526130768660405f20612ae3565b845f528060205261308d82600160405f2001612ae3565b5f858152602091825260409081902043600382015542600482015560058101805460ff191660011790555f196006909101555160c0808252600a908201527f526561637469766174650000000000000000000000000000000000000000000060e082015261010091810182905295612f4f91870190612003565b9091503b156131cc576040517f95d89b410000000000000000000000000000000000000000000000000000000081525f81600481865afa5f91816131a8575b5061315c5750613154612cdc565b905b5f612d9d565b80511561316a575b90613156565b506040516131796040826121ca565b601281527f5343206e6f20746f6b656e2073796d626f6c00000000000000000000000000006020820152613164565b6131c59192503d805f833e6131bd81836121ca565b810190612d17565b905f613146565b6040516131da6040826121ca565b600d81527f77616c6c6574206e6f7420534300000000000000000000000000000000000000602082015290613156565b9350833b15613294576040517f06fdde030000000000000000000000000000000000000000000000000000000081525f81600481875afa5f9181613278575b5061325d5750613257612cdc565b93612d95565b80511561326a5793612d95565b50613273612cdc565b613257565b61328d9192503d805f833e6131bd81836121ca565b905f613249565b613257612cdc565b939290916001600160a01b03831692831561052357815115613709575b82511561360e575b50845f52600560205260405f20835f52806020526001600160a01b03600260405f2001541661343a576001906040516132f981612181565b8381526006876133488860208501898152604086018281526060870190438252612e2d608089019342855260a08a01958c875260c08b019889525f528a602052612e2460405f209a518b612ae3565b5191015501918254906801000000000000000082101561219d57613396827f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db9395600161341c95018155612530565b81549060031b906001600160a01b0388831b921b191617905561340e604051936133c16040866121ca565b600385527f416464000000000000000000000000000000000000000000000000000000000060208601526134006040519560c0875260c0870190612003565b908582036020870152612003565b908382036040850152612003565b934260608301526001608083015260a08201528033940390a4600190565b835f528060205260ff600560405f200154165f1461354557835f5280602052600660405f2001545f1981148080613539575b8115613520575b50612ff257855f198114159182613515575b5050613495575050505050505f90565b7f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db939261341c91855f5260205285600660405f20015561340e6040519360c08552600b60c08601527f55706461746556616c756500000000000000000000000000000000000000000060e08601526101006020860152610100850190612003565b14159050855f613485565b9050158061352f575b5f613473565b505f198614613529565b5f19881415915061346c565b7f71367fcf08ac1df09ac842d8b0c9188194c86b613e965f8b84fd2c2d3643db939261341c91855f528060205261357f8460405f20612ae3565b855f528060205261359682600160405f2001612ae3565b5f868152602091825260409081902043600382015542600482015560058101805460ff191660011790556006018890555160c0808252600a908201527f526561637469766174650000000000000000000000000000000000000000000060e08201526101009181018290529361340e91850190612003565b9091503b156136cb576040517f95d89b410000000000000000000000000000000000000000000000000000000081525f81600481865afa5f91816136af575b50613663575061365b612cdc565b905b5f6132c1565b805115613671575b9061365d565b506040516136806040826121ca565b601281527f5343206e6f20746f6b656e2073796d626f6c0000000000000000000000000000602082015261366b565b6136c49192503d805f833e6131bd81836121ca565b905f61364d565b6040516136d96040826121ca565b600d81527f77616c6c6574206e6f742053430000000000000000000000000000000000000060208201529061365d565b9050803b15613793576040517f06fdde030000000000000000000000000000000000000000000000000000000081525f81600481875afa5f9181613777575b5061375c5750613756612cdc565b906132b9565b80511561376957906132b9565b50613772612cdc565b613756565b61378c9192503d805f833e6131bd81836121ca565b905f613748565b613756612cdc565b906137d857508051156137b057805190602001fd5b7f1425ea42000000000000000000000000000000000000000000000000000000005f5260045ffd5b8151158061381e575b6137e9575090565b6001600160a01b03907f9996b315000000000000000000000000000000000000000000000000000000005f521660045260245ffd5b50803b156137e156fea26469706673582212201e176cd272a5b1358b41332457bd6236ad6011e71e6cabcc57048643f6de6dbc64736f6c634300081e0033

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

000000000000000000000000ead140af0ec3de7d47c18efc17b1b1e479f2326c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000000e55532046696e74656368204c4c43000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b55532046696e74656368204c4c43204e657720596f726b205553410000000000000000000000000000000000000000000000000000000000000000000000001f457175697479204d696e7420506c6174666f726d20616e64204d6f64656c7300000000000000000000000000000000000000000000000000000000000000000856342e332e302e35000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : projectSuperAddress (address): 0xEAD140AF0ec3de7D47C18efc17b1B1e479f2326c
Arg [1] : platformControllerAddress (address): 0x0000000000000000000000000000000000000000
Arg [2] : projectSuperName (string): US Fintech LLC
Arg [3] : projectSuperId (string): US Fintech LLC New York USA
Arg [4] : _projectName (string): Equity Mint Platform and Models
Arg [5] : _projectId (string): V4.3.0.5

-----Encoded View---------------
14 Constructor Arguments found :
Arg [0] : 000000000000000000000000ead140af0ec3de7d47c18efc17b1b1e479f2326c
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000180
Arg [6] : 000000000000000000000000000000000000000000000000000000000000000e
Arg [7] : 55532046696e74656368204c4c43000000000000000000000000000000000000
Arg [8] : 000000000000000000000000000000000000000000000000000000000000001b
Arg [9] : 55532046696e74656368204c4c43204e657720596f726b205553410000000000
Arg [10] : 000000000000000000000000000000000000000000000000000000000000001f
Arg [11] : 457175697479204d696e7420506c6174666f726d20616e64204d6f64656c7300
Arg [12] : 0000000000000000000000000000000000000000000000000000000000000008
Arg [13] : 56342e332e302e35000000000000000000000000000000000000000000000000


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

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.