{"file_path":"contracts/SyntheticToken.sol","creation_status":"success","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Initializable} from \"./dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol\";\nimport {IERC20} from \"./dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {SynthContext} from \"./utils/SynthContext.sol\";\nimport {WadRayMath} from \"./lib/WadRayMath.sol\";\nimport {IPool} from \"./interfaces/IPool.sol\";\nimport {IProxyOFT} from \"./interfaces/IProxyOFT.sol\";\nimport {IManageable} from \"./interfaces/IManageable.sol\";\nimport {IPoolRegistry} from \"./interfaces/IPoolRegistry.sol\";\nimport {ISyntheticToken} from \"./interfaces/ISyntheticToken.sol\";\nimport {IDebtToken} from \"./interfaces/IDebtToken.sol\";\nimport {SyntheticTokenStorageV2} from \"./storage/SyntheticTokenStorage.sol\";\n\nerror SenderIsNotGovernor();\nerror SenderCanNotBurn();\nerror SenderCanNotMint();\nerror SenderCanNotSeize();\nerror SyntheticIsInactive();\nerror NameIsNull();\nerror SymbolIsNull();\nerror DecimalsIsNull();\nerror PoolRegistryIsNull();\nerror DecreasedAllowanceBelowZero();\nerror AmountExceedsAllowance();\nerror ApproveFromTheZeroAddress();\nerror ApproveToTheZeroAddress();\nerror BurnFromTheZeroAddress();\nerror BurnAmountExceedsBalance();\nerror MintToTheZeroAddress();\nerror SurpassMaxBridgingSupply();\nerror SurpassMaxSynthSupply();\nerror TransferFromTheZeroAddress();\nerror TransferToTheZeroAddress();\nerror TransferAmountExceedsBalance();\nerror NewValueIsSameAsCurrent();\nerror AddressIsNull();\nerror SurpassMaxAmoSupply();\n\n/**\n * @title Synthetic Token contract\n */\ncontract SyntheticToken is SynthContext, Initializable, SyntheticTokenStorageV2 {\n    using WadRayMath for uint256;\n\n    string public constant VERSION = \"1.4.1\";\n\n    /// @notice Emitted when active flag is updated\n    event SyntheticTokenActiveUpdated(bool newActive);\n\n    /// @notice Emitted when max amo supply is updated\n    event MaxAmoSupplyUpdated(uint256 oldMaxAmoSupply, uint256 newMaxAmoSupply);\n\n    /// @notice Emitted when max total supply is updated\n    event MaxTotalSupplyUpdated(uint256 oldMaxTotalSupply, uint256 newMaxTotalSupply);\n\n    /// @notice Emitted when max bridged-in supply is updated\n    event MaxBridgedInSupplyUpdated(uint256 oldMaxBridgedInSupply, uint256 newMaxBridgedInSupply);\n\n    /// @notice Emitted when max bridged-out supply is updated\n    event MaxBridgedOutSupplyUpdated(uint256 oldMaxBridgedOutSupply, uint256 newMaxBridgedOutSupply);\n\n    /// @notice Emitted when proxyOFT is updated\n    event ProxyOFTUpdated(IProxyOFT oldProxyOFT, IProxyOFT newProxyOFT);\n\n    /// @notice Emitted when AMO is updated\n    event AmoUpdated(address oldAmo, address newAmo);\n\n    /**\n     * @notice Throws if caller isn't the governor\n     */\n    modifier onlyGovernor() {\n        if (_msgSender() != _poolRegistry.governor()) revert SenderIsNotGovernor();\n        _;\n    }\n\n    /**\n     * @dev Throws if sender can't burn\n     */\n    modifier onlyIfCanBurn() {\n        address _msgSender = _msgSender();\n        if (!_isProxyOFT(_msgSender) && !_isPool(_msgSender) && !_isDebtToken(_msgSender)) revert SenderCanNotBurn();\n        _;\n    }\n\n    /**\n     * @dev Throws if sender can't mint\n     */\n    modifier onlyIfCanMint() {\n        address _msgSender = _msgSender();\n        if (!_isProxyOFT(_msgSender) && !_isAmo(_msgSender) && !_isPool(_msgSender) && !_isDebtToken(_msgSender))\n            revert SenderCanNotMint();\n        _;\n    }\n\n    /**\n     * @dev Throws if sender can't seize\n     */\n    modifier onlyIfCanSeize() {\n        address _msgSender = _msgSender();\n        if (!_isProxyOFT(_msgSender) && !_isPool(_msgSender) && !_isDebtToken(_msgSender)) revert SenderCanNotSeize();\n        _;\n    }\n\n    /**\n     * @dev Throws if synthetic token isn't enabled\n     */\n    modifier onlyIfSyntheticTokenIsActive() {\n        if (!isActive) revert SyntheticIsInactive();\n        _;\n    }\n\n    constructor() {\n        _disableInitializers();\n    }\n\n    function initialize(\n        string calldata name_,\n        string calldata symbol_,\n        uint8 decimals_,\n        IPoolRegistry poolRegistry_\n    ) external initializer {\n        if (bytes(name_).length == 0) revert NameIsNull();\n        if (bytes(symbol_).length == 0) revert SymbolIsNull();\n        if (decimals_ == 0) revert DecimalsIsNull();\n        if (address(poolRegistry_) == address(0)) revert PoolRegistryIsNull();\n\n        _poolRegistry = poolRegistry_;\n        name = name_;\n        symbol = symbol_;\n        decimals = decimals_;\n        isActive = true;\n        maxTotalSupply = type(uint256).max;\n    }\n\n    /**\n     * @notice Set `amount` as the allowance of `spender` over the caller's tokens\n     */\n    function approve(address spender_, uint256 amount_) external override returns (bool) {\n        _approve(_msgSender(), spender_, amount_);\n        return true;\n    }\n\n    /**\n     * @notice Get net bridged-in circulating supply\n     * @dev The supply is calculated using `MAX(totalBridgedIn - totalBridgedOut, 0)`\n     */\n    function bridgedInSupply() public view returns (uint256 _supply) {\n        uint256 _totalBridgedIn = totalBridgedIn;\n        uint256 _totalBridgedOut = totalBridgedOut;\n\n        if (_totalBridgedIn > _totalBridgedOut) {\n            return _totalBridgedIn - _totalBridgedOut;\n        }\n    }\n\n    /**\n     * @notice Get net bridged-out circulating supply\n     * @dev The supply is calculated using `MAX(totalBridgedOut - totalBridgedIn, 0)`\n     */\n    function bridgedOutSupply() public view returns (uint256 _supply) {\n        uint256 _totalBridgedIn = totalBridgedIn;\n        uint256 _totalBridgedOut = totalBridgedOut;\n\n        if (_totalBridgedOut > _totalBridgedIn) {\n            return _totalBridgedOut - _totalBridgedIn;\n        }\n    }\n\n    /**\n     * @notice Burn synthetic token\n     * @param from_ The account to burn from\n     * @param amount_ The amount to burn\n     */\n    function burnFor(address from_, uint256 amount_) external override onlyIfCanBurn {\n        _burn(from_, amount_);\n    }\n\n    /**\n     * @notice Burn caller's synthetic tokens\n     * @param amount_ The amount to burn\n     */\n    function burn(uint256 amount_) external override {\n        _burn(_msgSender(), amount_);\n    }\n\n    /**\n     * @notice Burn synthetic tokens from `from_`, deducting from the caller's allowance\n     * @param from_ The account to burn from\n     * @param amount_ The amount to burn\n     */\n    function burnFrom(address from_, uint256 amount_) external override {\n        _spendAllowance(from_, _msgSender(), amount_);\n        _burn(from_, amount_);\n    }\n\n    /**\n     * @notice Atomically decrease the allowance granted to `spender` by the caller\n     */\n    function decreaseAllowance(address spender_, uint256 subtractedValue_) external returns (bool) {\n        address _msgSender = _msgSender();\n        uint256 _currentAllowance = allowance[_msgSender][spender_];\n        if (_currentAllowance < subtractedValue_) revert DecreasedAllowanceBelowZero();\n        unchecked {\n            _approve(_msgSender, spender_, _currentAllowance - subtractedValue_);\n        }\n        return true;\n    }\n\n    /**\n     * @notice Atomically increase the allowance granted to `spender` by the caller\n     */\n    function increaseAllowance(address spender_, uint256 addedValue_) external returns (bool) {\n        address _msgSender = _msgSender();\n        _approve(_msgSender, spender_, allowance[_msgSender][spender_] + addedValue_);\n        return true;\n    }\n\n    /**\n     * @notice Mint synthetic token\n     * @param to_ The account to mint to\n     * @param amount_ The amount to mint\n     */\n    function mint(address to_, uint256 amount_) external override onlyIfCanMint {\n        _mint(to_, amount_);\n    }\n\n    /**\n     * @notice Seize synthetic tokens\n     * @dev Same as _transfer\n     * @param to_ The account to seize from\n     * @param to_ The beneficiary account\n     * @param amount_ The amount to seize\n     */\n    function seize(address from_, address to_, uint256 amount_) external override onlyIfCanSeize {\n        if (_isProxyOFT(_msgSender()) && to_ != _poolRegistry.feeCollector()) revert SenderCanNotSeize();\n\n        _transfer(from_, to_, amount_);\n    }\n\n    /// @inheritdoc IERC20\n    function transfer(address to_, uint256 amount_) external override returns (bool) {\n        _transfer(_msgSender(), to_, amount_);\n        return true;\n    }\n\n    /// @inheritdoc IERC20\n    function transferFrom(address from_, address to_, uint256 amount_) external override returns (bool) {\n        _spendAllowance(from_, _msgSender(), amount_);\n\n        _transfer(from_, to_, amount_);\n\n        return true;\n    }\n\n    /**\n     * @notice Update `owner`'s allowance for `spender` based on spent `amount`\n     * @dev Maximum `uint256` means infinite allowance\n     */\n    function _spendAllowance(address owner_, address spender_, uint256 amount_) private {\n        uint256 _currentAllowance = allowance[owner_][spender_];\n        if (_currentAllowance != type(uint256).max) {\n            if (_currentAllowance < amount_) revert AmountExceedsAllowance();\n            unchecked {\n                _approve(owner_, spender_, _currentAllowance - amount_);\n            }\n        }\n    }\n\n    /**\n     * @notice Set `amount` as the allowance of `spender` over the `owner` s tokens\n     */\n    function _approve(address owner_, address spender_, uint256 amount_) private {\n        if (owner_ == address(0)) revert ApproveFromTheZeroAddress();\n        if (spender_ == address(0)) revert ApproveToTheZeroAddress();\n\n        allowance[owner_][spender_] = amount_;\n        emit Approval(owner_, spender_, amount_);\n    }\n\n    /**\n     * @notice Destroy `amount` tokens from `account`, reducing the\n     * total supply\n     */\n    function _burn(address account_, uint256 amount_) private {\n        if (account_ == address(0)) revert BurnFromTheZeroAddress();\n\n        address _msgSender = _msgSender();\n\n        if (_isProxyOFT(_msgSender)) {\n            totalBridgedOut += amount_;\n            if (bridgedOutSupply() > maxBridgedOutSupply) revert SurpassMaxBridgingSupply();\n        } else if (_isAmo(_msgSender)) {\n            amoSupply = amoSupply > amount_ ? amoSupply - amount_ : 0;\n        }\n\n        uint256 _currentBalance = balanceOf[account_];\n        if (_currentBalance < amount_) revert BurnAmountExceedsBalance();\n        unchecked {\n            balanceOf[account_] = _currentBalance - amount_;\n            totalSupply -= amount_;\n        }\n\n        emit Transfer(account_, address(0), amount_);\n    }\n\n    /**\n     * @dev Check if the account is AMO\n     */\n    function _isAmo(address account_) private view returns (bool) {\n        return account_ == amo;\n    }\n\n    /**\n     * @dev Check if the account is proxyOFT\n     */\n    function _isProxyOFT(address account_) private view returns (bool) {\n        return account_ == address(proxyOFT);\n    }\n\n    /**\n     * @notice Check if the account is a valid DebtToken contract\n     */\n    function _isDebtToken(address account_) private view returns (bool) {\n        IPool _pool = IManageable(account_).pool();\n\n        return\n            _poolRegistry.isPoolRegistered(address(_pool)) &&\n            _pool.doesDebtTokenExist(IDebtToken(account_)) &&\n            IDebtToken(account_).syntheticToken() == this;\n    }\n\n    /**\n     * @notice Check if the account is a valid Pool contract\n     */\n    function _isPool(address account_) private view returns (bool) {\n        return _poolRegistry.isPoolRegistered(account_) && IPool(account_).doesSyntheticTokenExist(this);\n    }\n\n    /**\n     * @notice Create `amount` tokens and assigns them to `account`, increasing\n     * the total supply\n     */\n    function _mint(address account_, uint256 amount_) private onlyIfSyntheticTokenIsActive {\n        if (account_ == address(0)) revert MintToTheZeroAddress();\n\n        address _msgSender = _msgSender();\n\n        if (_isProxyOFT(_msgSender)) {\n            totalBridgedIn += amount_;\n            if (bridgedInSupply() > maxBridgedInSupply) revert SurpassMaxBridgingSupply();\n        } else if (_isAmo(_msgSender)) {\n            amoSupply += amount_;\n            if (amoSupply > maxAmoSupply) revert SurpassMaxAmoSupply();\n        }\n\n        totalSupply += amount_;\n        if (totalSupply > maxTotalSupply) revert SurpassMaxSynthSupply();\n        balanceOf[account_] += amount_;\n        emit Transfer(address(0), account_, amount_);\n    }\n\n    /**\n     * @notice Move `amount` of tokens from `sender` to `recipient`\n     */\n    function _transfer(address sender_, address recipient_, uint256 amount_) private {\n        if (sender_ == address(0)) revert TransferFromTheZeroAddress();\n        if (recipient_ == address(0)) revert TransferToTheZeroAddress();\n\n        uint256 senderBalance = balanceOf[sender_];\n        if (senderBalance < amount_) revert TransferAmountExceedsBalance();\n        unchecked {\n            balanceOf[sender_] = senderBalance - amount_;\n            balanceOf[recipient_] += amount_;\n        }\n\n        emit Transfer(sender_, recipient_, amount_);\n    }\n\n    /**\n     * @notice Enable/Disable Synthetic Token\n     */\n    function toggleIsActive() external override onlyGovernor {\n        bool _newIsActive = !isActive;\n        emit SyntheticTokenActiveUpdated(_newIsActive);\n        isActive = _newIsActive;\n    }\n\n    /**\n     * Update AMO (Automated Marker Operator)\n     * @param newAmo_ new AMO address\n     */\n    function updateAmo(address newAmo_) external onlyGovernor {\n        address _currentAmo = amo;\n        if (newAmo_ == _currentAmo) revert NewValueIsSameAsCurrent();\n        emit AmoUpdated(_currentAmo, newAmo_);\n        amo = newAmo_;\n    }\n\n    /**\n     * @notice Update max synth supply for AMO.\n     * @param newMaxAmoSupply_ The new max synth supply for AMO\n     */\n    function updateMaxAmoSupply(uint256 newMaxAmoSupply_) external onlyGovernor {\n        uint256 _currentMaxAmoSupply = maxAmoSupply;\n        if (newMaxAmoSupply_ == _currentMaxAmoSupply) revert NewValueIsSameAsCurrent();\n        emit MaxAmoSupplyUpdated(_currentMaxAmoSupply, newMaxAmoSupply_);\n        maxAmoSupply = newMaxAmoSupply_;\n    }\n\n    /**\n     * @notice Update max total supply\n     * @param newMaxTotalSupply_ The new max total supply\n     */\n    function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external override onlyGovernor {\n        uint256 _currentMaxTotalSupply = maxTotalSupply;\n        if (newMaxTotalSupply_ == _currentMaxTotalSupply) revert NewValueIsSameAsCurrent();\n        emit MaxTotalSupplyUpdated(_currentMaxTotalSupply, newMaxTotalSupply_);\n        maxTotalSupply = newMaxTotalSupply_;\n    }\n\n    /**\n     * @notice Update max bridged-in supply\n     */\n    function updateMaxBridgedInSupply(uint256 maxBridgedInSupply_) external onlyGovernor {\n        uint256 _currentMaxBridgedInBalance = maxBridgedInSupply;\n        if (maxBridgedInSupply_ == _currentMaxBridgedInBalance) revert NewValueIsSameAsCurrent();\n        emit MaxBridgedInSupplyUpdated(_currentMaxBridgedInBalance, maxBridgedInSupply_);\n        maxBridgedInSupply = maxBridgedInSupply_;\n    }\n\n    /**\n     * @notice Update max bridged-out supply\n     */\n    function updateMaxBridgedOutSupply(uint256 maxBridgedOutSupply_) external onlyGovernor {\n        uint256 _currentMaxBridgedOutBalance = maxBridgedOutSupply;\n        if (maxBridgedOutSupply_ == _currentMaxBridgedOutBalance) revert NewValueIsSameAsCurrent();\n        emit MaxBridgedOutSupplyUpdated(_currentMaxBridgedOutBalance, maxBridgedOutSupply_);\n        maxBridgedOutSupply = maxBridgedOutSupply_;\n    }\n\n    /**\n     * @notice Update proxyOFT\n     * @param newProxyOFT_ Address of new ProxyOFT\n     */\n    function updateProxyOFT(IProxyOFT newProxyOFT_) external override onlyGovernor {\n        if (address(newProxyOFT_) == address(0)) revert AddressIsNull();\n        IProxyOFT _currentProxyOFT = proxyOFT;\n        if (newProxyOFT_ == _currentProxyOFT) revert NewValueIsSameAsCurrent();\n        emit ProxyOFTUpdated(_currentProxyOFT, newProxyOFT_);\n        proxyOFT = newProxyOFT_;\n    }\n\n    /// @inheritdoc SynthContext\n    function poolRegistry() public view override(ISyntheticToken, SynthContext) returns (IPoolRegistry) {\n        return _poolRegistry;\n    }\n}\n","deployed_bytecode":"0x608060405234801561000f575f80fd5b5060043610610229575f3560e01c806379cc67901161012a578063cbfa94de116100b4578063dd20d4f411610079578063dd20d4f414610485578063dd62ed3e14610498578063de7ea79d146104c2578063fa706552146104d5578063ffa1ad74146104e8575f80fd5b8063cbfa94de14610446578063cd2e986614610459578063d259332914610462578063d2f096851461046a578063d61f52ae14610472575f80fd5b8063a457c2d7116100fa578063a457c2d7146103e9578063a9059cbb146103fc578063afcff50f1461040f578063b2a02ff114610420578063c2ad98da14610433575f80fd5b806379cc6790146103b35780639163dd5f146103c657806393a04f13146103ce57806395d89b41146103e1575f80fd5b80632ab4d052116101b657806340c10f191161017b57806340c10f191461033a57806342966c681461034d57806344687c48146103605780636d1bb8f71461036957806370a0823114610394575f80fd5b80632ab4d052146102e65780632bb42183146102ef5780632f068bf1146102f8578063313ce567146103015780633950935114610327575f80fd5b806318160ddd116101fc57806318160ddd1461029a5780631ac571dd146102a35780631dd319cb146102ac57806322f3e2d4146102bf57806323b872dd146102d3575f80fd5b806306fdde031461022d578063095ea7b31461024b5780631543b9961461026e578063172f50a414610285575b5f80fd5b61023561050c565b6040516102429190611beb565b60405180910390f35b61025e610259366004611c4b565b610598565b6040519015158152602001610242565b610277600f5481565b604051908152602001610242565b610298610293366004611c75565b6105b5565b005b61027760055481565b610277600b5481565b6102986102ba366004611c4b565b6106c3565b60075461025e90600160a01b900460ff1681565b61025e6102e1366004611c8c565b610738565b61027760065481565b61027760095481565b610277600c5481565b60075461031590600160a81b900460ff1681565b60405160ff9091168152602001610242565b61025e610335366004611c4b565b610760565b610298610348366004611c4b565b6107aa565b61029861035b366004611c75565b610834565b610277600e5481565b60085461037c906001600160a01b031681565b6040516001600160a01b039091168152602001610242565b6102776103a2366004611cca565b60036020525f908152604090205481565b6102986103c1366004611c4b565b610848565b610277610868565b6102986103dc366004611c75565b61088f565b61023561099d565b61025e6103f7366004611c4b565b6109aa565b61025e61040a366004611c4b565b610a15565b6007546001600160a01b031661037c565b61029861042e366004611c8c565b610a28565b610298610441366004611c75565b610b6b565b610298610454366004611cca565b610c79565b610277600a5481565b610298610de3565b610277610ef0565b610298610480366004611cca565b610f0b565b610298610493366004611c75565b61104e565b6102776104a6366004611ce5565b600460209081525f928352604080842090915290825290205481565b6102986104d0366004611d61565b61115c565b600d5461037c906001600160a01b031681565b61023560405180604001604052806005815260200164312e342e3160d81b81525081565b6001805461051990611df5565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611df5565b80156105905780601f1061056757610100808354040283529160200191610590565b820191905f5260205f20905b81548152906001019060200180831161057357829003601f168201915b505050505081565b5f6105ab6105a46112bc565b84846113bd565b5060015b92915050565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610605573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106299190611e2d565b6001600160a01b031661063a6112bc565b6001600160a01b03161461066157604051634b98449160e11b815260040160405180910390fd5b60065480820361068457604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527fc58cd6132bb46df23d468939c03dd023b74b509aaa6b04c39d5a6461c65963bd910160405180910390a150600655565b5f6106cc6112bc565b90506106e6816008546001600160a01b0391821691161490565b1580156106f957506106f78161146c565b155b801561070b575061070981611545565b155b156107295760405163848003b560e01b815260040160405180910390fd5b6107338383611707565b505050565b5f61074b846107456112bc565b8461186b565b6107568484846118c6565b5060019392505050565b5f8061076a6112bc565b6001600160a01b038082165f9081526004602090815260408083209389168352929052205490915061075690829086906107a5908790611e5c565b6113bd565b5f6107b36112bc565b90506107cd816008546001600160a01b0391821691161490565b1580156107e85750600d546001600160a01b03828116911614155b80156107fa57506107f88161146c565b155b801561080c575061080a81611545565b155b1561082a5760405163168504c160e21b815260040160405180910390fd5b61073383836119ac565b61084561083f6112bc565b82611707565b50565b61085a826108546112bc565b8361186b565b6108648282611707565b5050565b600954600a545f91908082111561088a576108838183611e6f565b9250505090565b505090565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108df573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109039190611e2d565b6001600160a01b03166109146112bc565b6001600160a01b03161461093b57604051634b98449160e11b815260040160405180910390fd5b600b5480820361095e57604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527feacf40fa755daf182276c22cc2ad53893a50e8d3d4c73132308548febf636764910160405180910390a150600b55565b6002805461051990611df5565b5f806109b46112bc565b6001600160a01b038082165f90815260046020908152604080832093891683529290522054909150838110156109fd5760405163189dd6af60e31b815260040160405180910390fd5b610a0a82868684036113bd565b506001949350505050565b5f6105ab610a216112bc565b84846118c6565b5f610a316112bc565b9050610a4b816008546001600160a01b0391821691161490565b158015610a5e5750610a5c8161146c565b155b8015610a705750610a6e81611545565b155b15610a8d576040516249987f60e01b815260040160405180910390fd5b610aac610a986112bc565b6008546001600160a01b0391821691161490565b8015610b3d575060075f9054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b03573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b279190611e2d565b6001600160a01b0316836001600160a01b031614155b15610b5a576040516249987f60e01b815260040160405180910390fd5b610b658484846118c6565b50505050565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bbb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bdf9190611e2d565b6001600160a01b0316610bf06112bc565b6001600160a01b031614610c1757604051634b98449160e11b815260040160405180910390fd5b600e54808203610c3a57604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527f81b58019269269420514e5621049a5ee019eb39169b2b0e30a4d81392fd6869a910160405180910390a150600e55565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cc9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ced9190611e2d565b6001600160a01b0316610cfe6112bc565b6001600160a01b031614610d2557604051634b98449160e11b815260040160405180910390fd5b6001600160a01b038116610d4c5760405163fb7566d760e01b815260040160405180910390fd5b6008546001600160a01b03908116908216819003610d7d57604051630333a68160e41b815260040160405180910390fd5b604080516001600160a01b038084168252841660208201527fef71fdb6fc3b4bdacae0b7871edf00279c204dc041134e4304cf93935cf07af7910160405180910390a150600880546001600160a01b0319166001600160a01b0392909216919091179055565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e33573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e579190611e2d565b6001600160a01b0316610e686112bc565b6001600160a01b031614610e8f57604051634b98449160e11b815260040160405180910390fd5b600754604051600160a01b90910460ff1615808252907f79e35d0afb37464963b458a448d257d695a4dc4406dc45df01e4c7b38e2732cb9060200160405180910390a160078054911515600160a01b0260ff60a01b19909216919091179055565b600954600a545f91908181111561088a576108838282611e6f565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f5b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f7f9190611e2d565b6001600160a01b0316610f906112bc565b6001600160a01b031614610fb757604051634b98449160e11b815260040160405180910390fd5b600d546001600160a01b03908116908216819003610fe857604051630333a68160e41b815260040160405180910390fd5b604080516001600160a01b038084168252841660208201527f866387c95e49cc0d92347a543d711fca6a43f64961037c10cafcb7b9d38ba3e6910160405180910390a150600d80546001600160a01b0319166001600160a01b0392909216919091179055565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa15801561109e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110c29190611e2d565b6001600160a01b03166110d36112bc565b6001600160a01b0316146110fa57604051634b98449160e11b815260040160405180910390fd5b600c5480820361111d57604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527ff0d21a56ee8d766c9055580b458227594b5f2d86aa9087573908bea9dc4ca3d6910160405180910390a150600c55565b5f6111676001611b5e565b9050801561117e575f805461ff0019166101001790555b5f86900361119f57604051636e83f50760e01b815260040160405180910390fd5b5f8490036111c0576040516330507cff60e11b815260040160405180910390fd5b8260ff165f036111e357604051634dc4784160e11b815260040160405180910390fd5b6001600160a01b03821661120a57604051637cb62f2b60e11b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0384161790556001611232878983611ee1565b506002611240858783611ee1565b506007805460ff60a01b1960ff8616600160a81b021661ffff60a01b1990911617600160a01b1790555f1960065580156112b3575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b5f806112d06007546001600160a01b031690565b90506001600160a01b038116156113b6575f816001600160a01b031663570ca7356040518163ffffffff1660e01b8152600401602060405180830381865afa15801561131e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113429190611e2d565b90506001600160a01b03811633036113b457806001600160a01b031663d2c869a46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611390573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108839190611e2d565b505b3391505090565b6001600160a01b0383166113e4576040516356fdae6560e11b815260040160405180910390fd5b6001600160a01b03821661140b5760405163b2fa1ef360e01b815260040160405180910390fd5b6001600160a01b038381165f8181526004602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60075460405163c673bdaf60e01b81526001600160a01b0383811660048301525f92169063c673bdaf90602401602060405180830381865afa1580156114b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114d89190611f9b565b80156105af5750604051631a0dd00b60e01b81523060048201526001600160a01b03831690631a0dd00b90602401602060405180830381865afa158015611521573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105af9190611f9b565b5f80826001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611583573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115a79190611e2d565b60075460405163c673bdaf60e01b81526001600160a01b03808416600483015292935091169063c673bdaf90602401602060405180830381865afa1580156115f1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116159190611f9b565b801561168457506040516308a00b1f60e31b81526001600160a01b03848116600483015282169063450058f890602401602060405180830381865afa158015611660573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116849190611f9b565b80156117005750306001600160a01b0316836001600160a01b0316638230ecd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116d1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116f59190611e2d565b6001600160a01b0316145b9392505050565b6001600160a01b03821661172e576040516304fca6bd60e41b815260040160405180910390fd5b5f6117376112bc565b9050611751816008546001600160a01b0391821691161490565b1561179b5781600a5f8282546117679190611e5c565b9091555050600c54611777610ef0565b111561179657604051639da48d2560e01b815260040160405180910390fd5b6117d1565b600d546001600160a01b038281169116036117d15781600f54116117bf575f6117cd565b81600f546117cd9190611e6f565b600f555b6001600160a01b0383165f908152600360205260409020548281101561180a57604051630bba337f60e11b815260040160405180910390fd5b6001600160a01b0384165f8181526003602090815260408083208786039055600580548890039055518681529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a350505050565b6001600160a01b038084165f908152600460209081526040808320938616835292905220545f198114610b6557818110156118b9576040516303814af160e61b815260040160405180910390fd5b610b6584848484036113bd565b6001600160a01b0383166118ed57604051630240531760e41b815260040160405180910390fd5b6001600160a01b0382166119145760405163671d1add60e11b815260040160405180910390fd5b6001600160a01b0383165f908152600360205260409020548181101561194d57604051635dd58b8b60e01b815260040160405180910390fd5b6001600160a01b038085165f8181526003602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061185d9086815260200190565b600754600160a01b900460ff166119d6576040516303127d9160e31b815260040160405180910390fd5b6001600160a01b0382166119fd5760405163c96c2a0b60e01b815260040160405180910390fd5b5f611a066112bc565b9050611a20816008546001600160a01b0391821691161490565b15611a6a578160095f828254611a369190611e5c565b9091555050600b54611a46610868565b1115611a6557604051639da48d2560e01b815260040160405180910390fd5b611aba565b600d546001600160a01b03828116911603611aba5781600f5f828254611a909190611e5c565b9091555050600e54600f541115611aba57604051631693bff760e21b815260040160405180910390fd5b8160055f828254611acb9190611e5c565b90915550506006546005541115611af5576040516309e0f0fd60e31b815260040160405180910390fd5b6001600160a01b0383165f9081526003602052604081208054849290611b1c908490611e5c565b90915550506040518281526001600160a01b038416905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200161145f565b5f8054610100900460ff1615611bac578160ff166001148015611b805750303b155b611ba55760405162461bcd60e51b8152600401611b9c90611fba565b60405180910390fd5b505f919050565b5f5460ff808416911610611bd25760405162461bcd60e51b8152600401611b9c90611fba565b505f805460ff191660ff92909216919091179055600190565b5f602080835283518060208501525f5b81811015611c1757858101830151858201604001528201611bfb565b505f604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b0381168114610845575f80fd5b5f8060408385031215611c5c575f80fd5b8235611c6781611c37565b946020939093013593505050565b5f60208284031215611c85575f80fd5b5035919050565b5f805f60608486031215611c9e575f80fd5b8335611ca981611c37565b92506020840135611cb981611c37565b929592945050506040919091013590565b5f60208284031215611cda575f80fd5b813561170081611c37565b5f8060408385031215611cf6575f80fd5b8235611d0181611c37565b91506020830135611d1181611c37565b809150509250929050565b5f8083601f840112611d2c575f80fd5b50813567ffffffffffffffff811115611d43575f80fd5b602083019150836020828501011115611d5a575f80fd5b9250929050565b5f805f805f8060808789031215611d76575f80fd5b863567ffffffffffffffff80821115611d8d575f80fd5b611d998a838b01611d1c565b90985096506020890135915080821115611db1575f80fd5b50611dbe89828a01611d1c565b909550935050604087013560ff81168114611dd7575f80fd5b91506060870135611de781611c37565b809150509295509295509295565b600181811c90821680611e0957607f821691505b602082108103611e2757634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215611e3d575f80fd5b815161170081611c37565b634e487b7160e01b5f52601160045260245ffd5b808201808211156105af576105af611e48565b818103818111156105af576105af611e48565b634e487b7160e01b5f52604160045260245ffd5b601f82111561073357805f5260205f20601f840160051c81016020851015611ebb5750805b601f840160051c820191505b81811015611eda575f8155600101611ec7565b5050505050565b67ffffffffffffffff831115611ef957611ef9611e82565b611f0d83611f078354611df5565b83611e96565b5f601f841160018114611f3e575f8515611f275750838201355b5f19600387901b1c1916600186901b178355611eda565b5f83815260208120601f198716915b82811015611f6d5786850135825560209485019460019092019101611f4d565b5086821015611f89575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f60208284031215611fab575f80fd5b81518015158114611700575f80fd5b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b60608201526080019056fea26469706673582212207286b643e4c5bb32ced689bc07abb1d905365d2f0765a6f473659adde91d5bdc64736f6c63430008180033","optimization_enabled":true,"verified_twin_address_hash":null,"is_verified":true,"compiler_settings":{"evmVersion":"cancun","libraries":{},"metadata":{"useLiteralContent":true},"optimizer":{"enabled":true,"runs":200},"outputSelection":{"*":{"":["*"],"*":["*"]}}},"optimization_runs":200,"sourcify_repo_url":null,"decoded_constructor_args":null,"compiler_version":"v0.8.24+commit.e11b9ed9","is_verified_via_verifier_alliance":false,"verified_at":"2026-10-01T21:02:26.022828Z","implementations":[],"proxy_type":null,"external_libraries":[],"creation_bytecode":"0x608060405234801562000010575f80fd5b506200001b62000021565b62000128565b6200002d60ff62000030565b50565b5f8054610100900460ff1615620000b2578160ff166001148015620000545750303b155b620000ab5760405162461bcd60e51b815260206004820152602e60248201525f805160206200217483398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b505f919050565b5f5460ff8084169116106200010f5760405162461bcd60e51b815260206004820152602e60248201525f805160206200217483398151915260448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401620000a2565b505f805460ff191660ff92909216919091179055600190565b61203e80620001365f395ff3fe608060405234801561000f575f80fd5b5060043610610229575f3560e01c806379cc67901161012a578063cbfa94de116100b4578063dd20d4f411610079578063dd20d4f414610485578063dd62ed3e14610498578063de7ea79d146104c2578063fa706552146104d5578063ffa1ad74146104e8575f80fd5b8063cbfa94de14610446578063cd2e986614610459578063d259332914610462578063d2f096851461046a578063d61f52ae14610472575f80fd5b8063a457c2d7116100fa578063a457c2d7146103e9578063a9059cbb146103fc578063afcff50f1461040f578063b2a02ff114610420578063c2ad98da14610433575f80fd5b806379cc6790146103b35780639163dd5f146103c657806393a04f13146103ce57806395d89b41146103e1575f80fd5b80632ab4d052116101b657806340c10f191161017b57806340c10f191461033a57806342966c681461034d57806344687c48146103605780636d1bb8f71461036957806370a0823114610394575f80fd5b80632ab4d052146102e65780632bb42183146102ef5780632f068bf1146102f8578063313ce567146103015780633950935114610327575f80fd5b806318160ddd116101fc57806318160ddd1461029a5780631ac571dd146102a35780631dd319cb146102ac57806322f3e2d4146102bf57806323b872dd146102d3575f80fd5b806306fdde031461022d578063095ea7b31461024b5780631543b9961461026e578063172f50a414610285575b5f80fd5b61023561050c565b6040516102429190611beb565b60405180910390f35b61025e610259366004611c4b565b610598565b6040519015158152602001610242565b610277600f5481565b604051908152602001610242565b610298610293366004611c75565b6105b5565b005b61027760055481565b610277600b5481565b6102986102ba366004611c4b565b6106c3565b60075461025e90600160a01b900460ff1681565b61025e6102e1366004611c8c565b610738565b61027760065481565b61027760095481565b610277600c5481565b60075461031590600160a81b900460ff1681565b60405160ff9091168152602001610242565b61025e610335366004611c4b565b610760565b610298610348366004611c4b565b6107aa565b61029861035b366004611c75565b610834565b610277600e5481565b60085461037c906001600160a01b031681565b6040516001600160a01b039091168152602001610242565b6102776103a2366004611cca565b60036020525f908152604090205481565b6102986103c1366004611c4b565b610848565b610277610868565b6102986103dc366004611c75565b61088f565b61023561099d565b61025e6103f7366004611c4b565b6109aa565b61025e61040a366004611c4b565b610a15565b6007546001600160a01b031661037c565b61029861042e366004611c8c565b610a28565b610298610441366004611c75565b610b6b565b610298610454366004611cca565b610c79565b610277600a5481565b610298610de3565b610277610ef0565b610298610480366004611cca565b610f0b565b610298610493366004611c75565b61104e565b6102776104a6366004611ce5565b600460209081525f928352604080842090915290825290205481565b6102986104d0366004611d61565b61115c565b600d5461037c906001600160a01b031681565b61023560405180604001604052806005815260200164312e342e3160d81b81525081565b6001805461051990611df5565b80601f016020809104026020016040519081016040528092919081815260200182805461054590611df5565b80156105905780601f1061056757610100808354040283529160200191610590565b820191905f5260205f20905b81548152906001019060200180831161057357829003601f168201915b505050505081565b5f6105ab6105a46112bc565b84846113bd565b5060015b92915050565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610605573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106299190611e2d565b6001600160a01b031661063a6112bc565b6001600160a01b03161461066157604051634b98449160e11b815260040160405180910390fd5b60065480820361068457604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527fc58cd6132bb46df23d468939c03dd023b74b509aaa6b04c39d5a6461c65963bd910160405180910390a150600655565b5f6106cc6112bc565b90506106e6816008546001600160a01b0391821691161490565b1580156106f957506106f78161146c565b155b801561070b575061070981611545565b155b156107295760405163848003b560e01b815260040160405180910390fd5b6107338383611707565b505050565b5f61074b846107456112bc565b8461186b565b6107568484846118c6565b5060019392505050565b5f8061076a6112bc565b6001600160a01b038082165f9081526004602090815260408083209389168352929052205490915061075690829086906107a5908790611e5c565b6113bd565b5f6107b36112bc565b90506107cd816008546001600160a01b0391821691161490565b1580156107e85750600d546001600160a01b03828116911614155b80156107fa57506107f88161146c565b155b801561080c575061080a81611545565b155b1561082a5760405163168504c160e21b815260040160405180910390fd5b61073383836119ac565b61084561083f6112bc565b82611707565b50565b61085a826108546112bc565b8361186b565b6108648282611707565b5050565b600954600a545f91908082111561088a576108838183611e6f565b9250505090565b505090565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108df573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109039190611e2d565b6001600160a01b03166109146112bc565b6001600160a01b03161461093b57604051634b98449160e11b815260040160405180910390fd5b600b5480820361095e57604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527feacf40fa755daf182276c22cc2ad53893a50e8d3d4c73132308548febf636764910160405180910390a150600b55565b6002805461051990611df5565b5f806109b46112bc565b6001600160a01b038082165f90815260046020908152604080832093891683529290522054909150838110156109fd5760405163189dd6af60e31b815260040160405180910390fd5b610a0a82868684036113bd565b506001949350505050565b5f6105ab610a216112bc565b84846118c6565b5f610a316112bc565b9050610a4b816008546001600160a01b0391821691161490565b158015610a5e5750610a5c8161146c565b155b8015610a705750610a6e81611545565b155b15610a8d576040516249987f60e01b815260040160405180910390fd5b610aac610a986112bc565b6008546001600160a01b0391821691161490565b8015610b3d575060075f9054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b03573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b279190611e2d565b6001600160a01b0316836001600160a01b031614155b15610b5a576040516249987f60e01b815260040160405180910390fd5b610b658484846118c6565b50505050565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bbb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bdf9190611e2d565b6001600160a01b0316610bf06112bc565b6001600160a01b031614610c1757604051634b98449160e11b815260040160405180910390fd5b600e54808203610c3a57604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527f81b58019269269420514e5621049a5ee019eb39169b2b0e30a4d81392fd6869a910160405180910390a150600e55565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cc9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ced9190611e2d565b6001600160a01b0316610cfe6112bc565b6001600160a01b031614610d2557604051634b98449160e11b815260040160405180910390fd5b6001600160a01b038116610d4c5760405163fb7566d760e01b815260040160405180910390fd5b6008546001600160a01b03908116908216819003610d7d57604051630333a68160e41b815260040160405180910390fd5b604080516001600160a01b038084168252841660208201527fef71fdb6fc3b4bdacae0b7871edf00279c204dc041134e4304cf93935cf07af7910160405180910390a150600880546001600160a01b0319166001600160a01b0392909216919091179055565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e33573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e579190611e2d565b6001600160a01b0316610e686112bc565b6001600160a01b031614610e8f57604051634b98449160e11b815260040160405180910390fd5b600754604051600160a01b90910460ff1615808252907f79e35d0afb37464963b458a448d257d695a4dc4406dc45df01e4c7b38e2732cb9060200160405180910390a160078054911515600160a01b0260ff60a01b19909216919091179055565b600954600a545f91908181111561088a576108838282611e6f565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f5b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f7f9190611e2d565b6001600160a01b0316610f906112bc565b6001600160a01b031614610fb757604051634b98449160e11b815260040160405180910390fd5b600d546001600160a01b03908116908216819003610fe857604051630333a68160e41b815260040160405180910390fd5b604080516001600160a01b038084168252841660208201527f866387c95e49cc0d92347a543d711fca6a43f64961037c10cafcb7b9d38ba3e6910160405180910390a150600d80546001600160a01b0319166001600160a01b0392909216919091179055565b60075f9054906101000a90046001600160a01b03166001600160a01b0316630c340a246040518163ffffffff1660e01b8152600401602060405180830381865afa15801561109e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110c29190611e2d565b6001600160a01b03166110d36112bc565b6001600160a01b0316146110fa57604051634b98449160e11b815260040160405180910390fd5b600c5480820361111d57604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527ff0d21a56ee8d766c9055580b458227594b5f2d86aa9087573908bea9dc4ca3d6910160405180910390a150600c55565b5f6111676001611b5e565b9050801561117e575f805461ff0019166101001790555b5f86900361119f57604051636e83f50760e01b815260040160405180910390fd5b5f8490036111c0576040516330507cff60e11b815260040160405180910390fd5b8260ff165f036111e357604051634dc4784160e11b815260040160405180910390fd5b6001600160a01b03821661120a57604051637cb62f2b60e11b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b0384161790556001611232878983611ee1565b506002611240858783611ee1565b506007805460ff60a01b1960ff8616600160a81b021661ffff60a01b1990911617600160a01b1790555f1960065580156112b3575f805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b5f806112d06007546001600160a01b031690565b90506001600160a01b038116156113b6575f816001600160a01b031663570ca7356040518163ffffffff1660e01b8152600401602060405180830381865afa15801561131e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113429190611e2d565b90506001600160a01b03811633036113b457806001600160a01b031663d2c869a46040518163ffffffff1660e01b8152600401602060405180830381865afa158015611390573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108839190611e2d565b505b3391505090565b6001600160a01b0383166113e4576040516356fdae6560e11b815260040160405180910390fd5b6001600160a01b03821661140b5760405163b2fa1ef360e01b815260040160405180910390fd5b6001600160a01b038381165f8181526004602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60075460405163c673bdaf60e01b81526001600160a01b0383811660048301525f92169063c673bdaf90602401602060405180830381865afa1580156114b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114d89190611f9b565b80156105af5750604051631a0dd00b60e01b81523060048201526001600160a01b03831690631a0dd00b90602401602060405180830381865afa158015611521573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105af9190611f9b565b5f80826001600160a01b03166316f0115b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611583573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115a79190611e2d565b60075460405163c673bdaf60e01b81526001600160a01b03808416600483015292935091169063c673bdaf90602401602060405180830381865afa1580156115f1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116159190611f9b565b801561168457506040516308a00b1f60e31b81526001600160a01b03848116600483015282169063450058f890602401602060405180830381865afa158015611660573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116849190611f9b565b80156117005750306001600160a01b0316836001600160a01b0316638230ecd66040518163ffffffff1660e01b8152600401602060405180830381865afa1580156116d1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116f59190611e2d565b6001600160a01b0316145b9392505050565b6001600160a01b03821661172e576040516304fca6bd60e41b815260040160405180910390fd5b5f6117376112bc565b9050611751816008546001600160a01b0391821691161490565b1561179b5781600a5f8282546117679190611e5c565b9091555050600c54611777610ef0565b111561179657604051639da48d2560e01b815260040160405180910390fd5b6117d1565b600d546001600160a01b038281169116036117d15781600f54116117bf575f6117cd565b81600f546117cd9190611e6f565b600f555b6001600160a01b0383165f908152600360205260409020548281101561180a57604051630bba337f60e11b815260040160405180910390fd5b6001600160a01b0384165f8181526003602090815260408083208786039055600580548890039055518681529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91015b60405180910390a350505050565b6001600160a01b038084165f908152600460209081526040808320938616835292905220545f198114610b6557818110156118b9576040516303814af160e61b815260040160405180910390fd5b610b6584848484036113bd565b6001600160a01b0383166118ed57604051630240531760e41b815260040160405180910390fd5b6001600160a01b0382166119145760405163671d1add60e11b815260040160405180910390fd5b6001600160a01b0383165f908152600360205260409020548181101561194d57604051635dd58b8b60e01b815260040160405180910390fd5b6001600160a01b038085165f8181526003602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9061185d9086815260200190565b600754600160a01b900460ff166119d6576040516303127d9160e31b815260040160405180910390fd5b6001600160a01b0382166119fd5760405163c96c2a0b60e01b815260040160405180910390fd5b5f611a066112bc565b9050611a20816008546001600160a01b0391821691161490565b15611a6a578160095f828254611a369190611e5c565b9091555050600b54611a46610868565b1115611a6557604051639da48d2560e01b815260040160405180910390fd5b611aba565b600d546001600160a01b03828116911603611aba5781600f5f828254611a909190611e5c565b9091555050600e54600f541115611aba57604051631693bff760e21b815260040160405180910390fd5b8160055f828254611acb9190611e5c565b90915550506006546005541115611af5576040516309e0f0fd60e31b815260040160405180910390fd5b6001600160a01b0383165f9081526003602052604081208054849290611b1c908490611e5c565b90915550506040518281526001600160a01b038416905f907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200161145f565b5f8054610100900460ff1615611bac578160ff166001148015611b805750303b155b611ba55760405162461bcd60e51b8152600401611b9c90611fba565b60405180910390fd5b505f919050565b5f5460ff808416911610611bd25760405162461bcd60e51b8152600401611b9c90611fba565b505f805460ff191660ff92909216919091179055600190565b5f602080835283518060208501525f5b81811015611c1757858101830151858201604001528201611bfb565b505f604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b0381168114610845575f80fd5b5f8060408385031215611c5c575f80fd5b8235611c6781611c37565b946020939093013593505050565b5f60208284031215611c85575f80fd5b5035919050565b5f805f60608486031215611c9e575f80fd5b8335611ca981611c37565b92506020840135611cb981611c37565b929592945050506040919091013590565b5f60208284031215611cda575f80fd5b813561170081611c37565b5f8060408385031215611cf6575f80fd5b8235611d0181611c37565b91506020830135611d1181611c37565b809150509250929050565b5f8083601f840112611d2c575f80fd5b50813567ffffffffffffffff811115611d43575f80fd5b602083019150836020828501011115611d5a575f80fd5b9250929050565b5f805f805f8060808789031215611d76575f80fd5b863567ffffffffffffffff80821115611d8d575f80fd5b611d998a838b01611d1c565b90985096506020890135915080821115611db1575f80fd5b50611dbe89828a01611d1c565b909550935050604087013560ff81168114611dd7575f80fd5b91506060870135611de781611c37565b809150509295509295509295565b600181811c90821680611e0957607f821691505b602082108103611e2757634e487b7160e01b5f52602260045260245ffd5b50919050565b5f60208284031215611e3d575f80fd5b815161170081611c37565b634e487b7160e01b5f52601160045260245ffd5b808201808211156105af576105af611e48565b818103818111156105af576105af611e48565b634e487b7160e01b5f52604160045260245ffd5b601f82111561073357805f5260205f20601f840160051c81016020851015611ebb5750805b601f840160051c820191505b81811015611eda575f8155600101611ec7565b5050505050565b67ffffffffffffffff831115611ef957611ef9611e82565b611f0d83611f078354611df5565b83611e96565b5f601f841160018114611f3e575f8515611f275750838201355b5f19600387901b1c1916600186901b178355611eda565b5f83815260208120601f198716915b82811015611f6d5786850135825560209485019460019092019101611f4d565b5086821015611f89575f1960f88860031b161c19848701351681555b505060018560011b0183555050505050565b5f60208284031215611fab575f80fd5b81518015158114611700575f80fd5b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b60608201526080019056fea26469706673582212207286b643e4c5bb32ced689bc07abb1d905365d2f0765a6f473659adde91d5bdc64736f6c63430008180033496e697469616c697a61626c653a20636f6e747261637420697320616c726561","name":"SyntheticToken","is_blueprint":false,"license_type":"none","is_fully_verified":true,"is_verified_via_eth_bytecode_db":true,"language":"solidity","evm_version":"cancun","can_be_visualized_via_sol2uml":true,"is_verified_via_sourcify":false,"additional_sources":[{"file_path":"contracts/dependencies/openzeppelin/utils/Context.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n    function _msgSender() internal view virtual returns (address) {\n        return msg.sender;\n    }\n\n    function _msgData() internal view virtual returns (bytes calldata) {\n        return msg.data;\n    }\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/IOFTCoreUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.2;\n\nimport \"../../../../../openzeppelin-upgradeable/utils/introspection/IERC165Upgradeable.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n */\ninterface IOFTCoreUpgradeable is IERC165Upgradeable {\n    /**\n     * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n     * _dstChainId - L0 defined chain id to send tokens too\n     * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n     * _amount - amount of the tokens to transfer\n     * _useZro - indicates to use zro to pay L0 fees\n     * _adapterParam - flexible bytes array to indicate messaging adapter services in L0\n     */\n    function estimateSendFee(\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) external view returns (uint nativeFee, uint zroFee);\n\n    /**\n     * @dev send `_amount` amount of token to (`_dstChainId`, `_toAddress`) from `_from`\n     * `_from` the owner of token\n     * `_dstChainId` the destination chain identifier\n     * `_toAddress` can be any size depending on the `dstChainId`.\n     * `_amount` the quantity of tokens in wei\n     * `_refundAddress` the address LayerZero refunds if too much message fee is sent\n     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)\n     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services\n     */\n    function sendFrom(\n        address _from,\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) external payable;\n\n    /**\n     * @dev returns the circulating amount of tokens on current chain\n     */\n    function circulatingSupply() external view returns (uint);\n\n    /**\n     * @dev returns the address of the ERC20 token\n     */\n    function token() external view returns (address);\n\n    /**\n     * @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n     * `_nonce` is the outbound nonce\n     */\n    event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes _toAddress, uint _amount);\n\n    /**\n     * @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n     * `_nonce` is the inbound nonce.\n     */\n    event ReceiveFromChain(uint16 indexed _srcChainId, address indexed _to, uint _amount);\n\n    event SetUseCustomAdapterParams(bool _useCustomAdapterParams);\n}\n"},{"file_path":"contracts/dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/composable/IComposableOFTCoreUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"../IOFTCoreUpgradeable.sol\";\n\n/**\n * @dev Interface of the composable OFT core standard\n */\ninterface IComposableOFTCoreUpgradeable is IOFTCoreUpgradeable {\n    function estimateSendAndCallFee(\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        bool _useZro,\n        bytes calldata _adapterParams\n    ) external view returns (uint nativeFee, uint zroFee);\n\n    function sendAndCall(\n        address _from,\n        uint16 _dstChainId,\n        bytes calldata _toAddress,\n        uint _amount,\n        bytes calldata _payload,\n        uint64 _dstGasForCall,\n        address payable _refundAddress,\n        address _zroPaymentAddress,\n        bytes calldata _adapterParams\n    ) external payable;\n\n    function retryOFTReceived(\n        uint16 _srcChainId,\n        bytes calldata _srcAddress,\n        uint64 _nonce,\n        bytes calldata _from,\n        address _to,\n        uint _amount,\n        bytes calldata _payload\n    ) external;\n\n    event CallOFTReceivedFailure(\n        uint16 indexed _srcChainId,\n        bytes _srcAddress,\n        uint64 _nonce,\n        bytes _from,\n        address indexed _to,\n        uint _amount,\n        bytes _payload,\n        bytes _reason\n    );\n\n    event CallOFTReceivedSuccess(uint16 indexed _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _hash);\n\n    event RetryOFTReceivedSuccess(bytes32 _messageHash);\n\n    event NonContractAddress(address _address);\n}\n"},{"file_path":"contracts/dependencies/openzeppelin-upgradeable/proxy/utils/Initializable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * contract MyToken is ERC20Upgradeable {\n *     function initialize() initializer public {\n *         __ERC20_init(\"MyToken\", \"MTK\");\n *     }\n * }\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\n *     function initializeV2() reinitializer(2) public {\n *         __ERC20Permit_init(\"MyToken\");\n *     }\n * }\n * ```\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n *\n * [CAUTION]\n * ====\n * Avoid leaving a contract uninitialized.\n *\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\n *\n * [.hljs-theme-light.nopadding]\n * ```\n * /// @custom:oz-upgrades-unsafe-allow constructor\n * constructor() {\n *     _disableInitializers();\n * }\n * ```\n * ====\n */\nabstract contract Initializable {\n    /**\n     * @dev Indicates that the contract has been initialized.\n     * @custom:oz-retyped-from bool\n     */\n    uint8 private _initialized;\n\n    /**\n     * @dev Indicates that the contract is in the process of being initialized.\n     */\n    bool private _initializing;\n\n    /**\n     * @dev Triggered when the contract has been initialized or reinitialized.\n     */\n    event Initialized(uint8 version);\n\n    /**\n     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n     * `onlyInitializing` functions can be used to initialize parent contracts. Equivalent to `reinitializer(1)`.\n     */\n    modifier initializer() {\n        bool isTopLevelCall = _setInitializedVersion(1);\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(1);\n        }\n    }\n\n    /**\n     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n     * used to initialize parent contracts.\n     *\n     * `initializer` is equivalent to `reinitializer(1)`, so a reinitializer may be used after the original\n     * initialization step. This is essential to configure modules that are added through upgrades and that require\n     * initialization.\n     *\n     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\n     * a contract, executing them in the right order is up to the developer or operator.\n     */\n    modifier reinitializer(uint8 version) {\n        bool isTopLevelCall = _setInitializedVersion(version);\n        if (isTopLevelCall) {\n            _initializing = true;\n        }\n        _;\n        if (isTopLevelCall) {\n            _initializing = false;\n            emit Initialized(version);\n        }\n    }\n\n    /**\n     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n     * {initializer} and {reinitializer} modifiers, directly or indirectly.\n     */\n    modifier onlyInitializing() {\n        require(_initializing, \"Initializable: contract is not initializing\");\n        _;\n    }\n\n    /**\n     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n     * through proxies.\n     */\n    function _disableInitializers() internal virtual {\n        _setInitializedVersion(type(uint8).max);\n    }\n\n    function _setInitializedVersion(uint8 version) private returns (bool) {\n        // If the contract is initializing we ignore whether _initialized is set in order to support multiple\n        // inheritance patterns, but we only do this in the context of a constructor, and for the lowest level\n        // of initializers, because in other contexts the contract may have been reentered.\n        if (_initializing) {\n            require(\n                version == 1 && !AddressUpgradeable.isContract(address(this)),\n                \"Initializable: contract is already initialized\"\n            );\n            return false;\n        } else {\n            require(_initialized < version, \"Initializable: contract is already initialized\");\n            _initialized = version;\n            return true;\n        }\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin-upgradeable/utils/AddressUpgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n    /**\n     * @dev Returns true if `account` is a contract.\n     *\n     * [IMPORTANT]\n     * ====\n     * It is unsafe to assume that an address for which this function returns\n     * false is an externally-owned account (EOA) and not a contract.\n     *\n     * Among others, `isContract` will return false for the following\n     * types of addresses:\n     *\n     *  - an externally-owned account\n     *  - a contract in construction\n     *  - an address where a contract will be created\n     *  - an address where a contract lived, but was destroyed\n     * ====\n     *\n     * [IMPORTANT]\n     * ====\n     * You shouldn't rely on `isContract` to protect against flash loan attacks!\n     *\n     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n     * constructor.\n     * ====\n     */\n    function isContract(address account) internal view returns (bool) {\n        // This method relies on extcodesize/address.code.length, which returns 0\n        // for contracts in construction, since the code is only stored at the end\n        // of the constructor execution.\n\n        return account.code.length > 0;\n    }\n\n    /**\n     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n     * `recipient`, forwarding all available gas and reverting on errors.\n     *\n     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n     * of certain opcodes, possibly making contracts go over the 2300 gas limit\n     * imposed by `transfer`, making them unable to receive funds via\n     * `transfer`. {sendValue} removes this limitation.\n     *\n     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n     *\n     * IMPORTANT: because control is transferred to `recipient`, care must be\n     * taken to not create reentrancy vulnerabilities. Consider using\n     * {ReentrancyGuard} or the\n     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n     */\n    function sendValue(address payable recipient, uint256 amount) internal {\n        require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n        (bool success, ) = recipient.call{value: amount}(\"\");\n        require(success, \"Address: unable to send value, recipient may have reverted\");\n    }\n\n    /**\n     * @dev Performs a Solidity function call using a low level `call`. A\n     * plain `call` is an unsafe replacement for a function call: use this\n     * function instead.\n     *\n     * If `target` reverts with a revert reason, it is bubbled up by this\n     * function (like regular Solidity function calls).\n     *\n     * Returns the raw returned data. To convert to the expected return value,\n     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n     *\n     * Requirements:\n     *\n     * - `target` must be a contract.\n     * - calling `target` with `data` must not revert.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n        return functionCall(target, data, \"Address: low-level call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n     * `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, 0, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but also transferring `value` wei to `target`.\n     *\n     * Requirements:\n     *\n     * - the calling contract must have an ETH balance of at least `value`.\n     * - the called Solidity function must be `payable`.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value\n    ) internal returns (bytes memory) {\n        return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n     * with `errorMessage` as a fallback revert reason when `target` reverts.\n     *\n     * _Available since v3.1._\n     */\n    function functionCallWithValue(\n        address target,\n        bytes memory data,\n        uint256 value,\n        string memory errorMessage\n    ) internal returns (bytes memory) {\n        require(address(this).balance >= value, \"Address: insufficient balance for call\");\n        require(isContract(target), \"Address: call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.call{value: value}(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n        return functionStaticCall(target, data, \"Address: low-level static call failed\");\n    }\n\n    /**\n     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n     * but performing a static call.\n     *\n     * _Available since v3.3._\n     */\n    function functionStaticCall(\n        address target,\n        bytes memory data,\n        string memory errorMessage\n    ) internal view returns (bytes memory) {\n        require(isContract(target), \"Address: static call to non-contract\");\n\n        (bool success, bytes memory returndata) = target.staticcall(data);\n        return verifyCallResult(success, returndata, errorMessage);\n    }\n\n    /**\n     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\n     * revert reason using the provided one.\n     *\n     * _Available since v4.3._\n     */\n    function verifyCallResult(\n        bool success,\n        bytes memory returndata,\n        string memory errorMessage\n    ) internal pure returns (bytes memory) {\n        if (success) {\n            return returndata;\n        } else {\n            // Look for revert reason and bubble it up if present\n            if (returndata.length > 0) {\n                // The easiest way to bubble the revert reason is using memory via assembly\n\n                assembly {\n                    let returndata_size := mload(returndata)\n                    revert(add(32, returndata), returndata_size)\n                }\n            } else {\n                revert(errorMessage);\n            }\n        }\n    }\n}\n"},{"file_path":"contracts/dependencies/openzeppelin-upgradeable/utils/introspection/IERC165Upgradeable.sol","source_code":"// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165Upgradeable {\n    /**\n     * @dev Returns true if this contract implements the interface defined by\n     * `interfaceId`. See the corresponding\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n     * to learn more about how these ids are created.\n     *\n     * This function call must use less than 30 000 gas.\n     */\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/token/ERC20/IERC20.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n    /**\n     * @dev Returns the amount of tokens in existence.\n     */\n    function totalSupply() external view returns (uint256);\n\n    /**\n     * @dev Returns the amount of tokens owned by `account`.\n     */\n    function balanceOf(address account) external view returns (uint256);\n\n    /**\n     * @dev Moves `amount` tokens from the caller's account to `recipient`.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transfer(address recipient, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Returns the remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}. This is\n     * zero by default.\n     *\n     * This value changes when {approve} or {transferFrom} are called.\n     */\n    function allowance(address owner, address spender) external view returns (uint256);\n\n    /**\n     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * IMPORTANT: Beware that changing an allowance with this method brings the risk\n     * that someone may use both the old and the new allowance by unfortunate\n     * transaction ordering. One possible solution to mitigate this race\n     * condition is to first reduce the spender's allowance to 0 and set the\n     * desired value afterwards:\n     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n     *\n     * Emits an {Approval} event.\n     */\n    function approve(address spender, uint256 amount) external returns (bool);\n\n    /**\n     * @dev Moves `amount` tokens from `sender` to `recipient` using the\n     * allowance mechanism. `amount` is then deducted from the caller's\n     * allowance.\n     *\n     * Returns a boolean value indicating whether the operation succeeded.\n     *\n     * Emits a {Transfer} event.\n     */\n    function transferFrom(\n        address sender,\n        address recipient,\n        uint256 amount\n    ) external returns (bool);\n\n    /**\n     * @dev Emitted when `value` tokens are moved from one account (`from`) to\n     * another (`to`).\n     *\n     * Note that `value` may be zero.\n     */\n    event Transfer(address indexed from, address indexed to, uint256 value);\n\n    /**\n     * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n     * a call to {approve}. `value` is the new allowance.\n     */\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"},{"file_path":"contracts/dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n    /**\n     * @dev Returns the name of the token.\n     */\n    function name() external view returns (string memory);\n\n    /**\n     * @dev Returns the symbol of the token.\n     */\n    function symbol() external view returns (string memory);\n\n    /**\n     * @dev Returns the decimals places of the token.\n     */\n    function decimals() external view returns (uint8);\n}\n"},{"file_path":"contracts/interfaces/IDebtToken.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20Metadata} from \"../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol\";\nimport {ISyntheticToken} from \"./ISyntheticToken.sol\";\n\ninterface IDebtToken is IERC20Metadata {\n    function lastTimestampAccrued() external view returns (uint256);\n\n    function isActive() external view returns (bool);\n\n    function syntheticToken() external view returns (ISyntheticToken);\n\n    function accrueInterest() external;\n\n    function debtIndex() external returns (uint256 debtIndex_);\n\n    function burnFor(address from_, uint256 amount_) external;\n\n    function issue(uint256 amount_, address to_) external returns (uint256 _issued, uint256 _fee);\n\n    function flashIssue(address to_, uint256 amount_) external returns (uint256 _issued, uint256 _fee);\n\n    function mint(address to_, uint256 amount_) external;\n\n    function repay(address onBehalfOf_, uint256 amount_) external returns (uint256 _repaid, uint256 _fee);\n\n    function repayAll(address onBehalfOf_) external returns (uint256 _repaid, uint256 _fee);\n\n    function quoteIssueIn(uint256 amountToIssue_) external view returns (uint256 _amount, uint256 _fee);\n\n    function quoteIssueOut(uint256 amount_) external view returns (uint256 _amountToIssue, uint256 _fee);\n\n    function quoteRepayIn(uint256 amountToRepay_) external view returns (uint256 _amount, uint256 _fee);\n\n    function quoteRepayOut(uint256 amount_) external view returns (uint256 _amountToRepay, uint256 _fee);\n\n    function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external;\n\n    function updateInterestRate(uint256 newInterestRate_) external;\n\n    function maxTotalSupply() external view returns (uint256);\n\n    function interestRate() external view returns (uint256);\n\n    function interestRatePerSecond() external view returns (uint256);\n\n    function toggleIsActive() external;\n}\n"},{"file_path":"contracts/interfaces/IDepositToken.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20Metadata, IERC20} from \"../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol\";\n\ninterface IDepositToken is IERC20Metadata {\n    function underlying() external view returns (IERC20);\n\n    function collateralFactor() external view returns (uint256);\n\n    function unlockedBalanceOf(address account_) external view returns (uint256);\n\n    function lockedBalanceOf(address account_) external view returns (uint256);\n\n    function flashWithdraw(address account_, uint256 amount_) external returns (uint256 _withdrawn, uint256 _fee);\n\n    function deposit(uint256 amount_, address onBehalfOf_) external returns (uint256 _deposited, uint256 _fee);\n\n    function quoteDepositIn(uint256 amountToDeposit_) external view returns (uint256 _amount, uint256 _fee);\n\n    function quoteDepositOut(uint256 amount_) external view returns (uint256 _amountToDeposit, uint256 _fee);\n\n    function quoteWithdrawIn(uint256 amountToWithdraw_) external view returns (uint256 _amount, uint256 _fee);\n\n    function quoteWithdrawOut(uint256 amount_) external view returns (uint256 _amountToWithdraw, uint256 _fee);\n\n    function withdraw(uint256 amount_, address to_) external returns (uint256 _withdrawn, uint256 _fee);\n\n    function seize(address from_, address to_, uint256 amount_) external;\n\n    function updateCollateralFactor(uint128 newCollateralFactor_) external;\n\n    function isActive() external view returns (bool);\n\n    function toggleIsActive() external;\n\n    function maxTotalSupply() external view returns (uint256);\n\n    function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external;\n\n    function withdrawFrom(address from_, uint256 amount_) external returns (uint256 _withdrawn, uint256 _fee);\n}\n"},{"file_path":"contracts/interfaces/IFeeProvider.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/**\n * @notice FeeProvider interface\n */\ninterface IFeeProvider {\n    struct LiquidationFees {\n        uint128 liquidatorIncentive;\n        uint128 protocolFee;\n    }\n\n    function swapFees(address synthIn, address synthOut) external view returns (uint256);\n\n    function depositFee() external view returns (uint256);\n\n    function issueFee() external view returns (uint256);\n\n    function liquidationFees() external view returns (uint128 liquidatorIncentive, uint128 protocolFee);\n\n    function repayFee() external view returns (uint256);\n\n    function withdrawFee() external view returns (uint256);\n}\n"},{"file_path":"contracts/interfaces/IGovernable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/**\n * @notice Governable interface\n */\ninterface IGovernable {\n    function governor() external view returns (address _governor);\n\n    function transferGovernorship(address _proposedGovernor) external;\n}\n"},{"file_path":"contracts/interfaces/IManageable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IPool} from \"./IPool.sol\";\n\n/**\n * @notice Manageable interface\n */\ninterface IManageable {\n    function pool() external view returns (IPool _pool);\n}\n"},{"file_path":"contracts/interfaces/IOperator.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface IOperator {\n    struct Call {\n        address target;\n        uint256 value;\n        bytes callData;\n    }\n\n    function getActualMsgSender() external view returns (address);\n\n    function execute(Call[] calldata calls_) external payable returns (bytes[] memory _returnData);\n}\n"},{"file_path":"contracts/interfaces/IPauseable.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface IPauseable {\n    function paused() external view returns (bool);\n\n    function everythingStopped() external view returns (bool);\n}\n"},{"file_path":"contracts/interfaces/IPool.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {IDepositToken} from \"./IDepositToken.sol\";\nimport {IDebtToken} from \"./IDebtToken.sol\";\nimport {ITreasury} from \"./ITreasury.sol\";\nimport {IPoolRegistry} from \"./IPoolRegistry.sol\";\nimport {IFeeProvider} from \"./IFeeProvider.sol\";\nimport {ISmartFarmingManager} from \"./ISmartFarmingManager.sol\";\nimport {IFeeProvider} from \"../interfaces/IFeeProvider.sol\";\nimport {IPauseable} from \"../interfaces/IPauseable.sol\";\nimport {IGovernable} from \"../interfaces/IGovernable.sol\";\nimport {ISyntheticToken} from \"../interfaces/ISyntheticToken.sol\";\nimport {IMasterOracle} from \"../interfaces/external/IMasterOracle.sol\";\n\n/**\n * @notice Pool interface\n */\ninterface IPool is IPauseable, IGovernable {\n    function debtFloorInUsd() external view returns (uint256);\n\n    function feeCollector() external view returns (address);\n\n    function feeProvider() external view returns (IFeeProvider);\n\n    function maxLiquidable() external view returns (uint256);\n\n    function doesSyntheticTokenExist(ISyntheticToken syntheticToken_) external view returns (bool);\n\n    function doesDebtTokenExist(IDebtToken debtToken_) external view returns (bool);\n\n    function doesDepositTokenExist(IDepositToken depositToken_) external view returns (bool);\n\n    function depositTokenOf(IERC20 underlying_) external view returns (IDepositToken);\n\n    function debtTokenOf(ISyntheticToken syntheticToken_) external view returns (IDebtToken);\n\n    function getDepositTokens() external view returns (address[] memory);\n\n    function getDebtTokens() external view returns (address[] memory);\n\n    function getRewardsDistributors() external view returns (address[] memory);\n\n    function debtOf(address account_) external view returns (uint256 _debtInUsd);\n\n    function depositOf(address account_) external view returns (uint256 _depositInUsd, uint256 _issuableLimitInUsd);\n\n    function debtPositionOf(\n        address account_\n    )\n        external\n        view\n        returns (\n            bool _isHealthy,\n            uint256 _depositInUsd,\n            uint256 _debtInUsd,\n            uint256 _issuableLimitInUsd,\n            uint256 _issuableInUsd\n        );\n\n    function liquidate(\n        ISyntheticToken syntheticToken_,\n        address account_,\n        uint256 amountToRepay_,\n        IDepositToken depositToken_\n    ) external returns (uint256 _totalSeized, uint256 _toLiquidator, uint256 _fee);\n\n    function quoteLiquidateIn(\n        ISyntheticToken syntheticToken_,\n        uint256 totalToSeized_,\n        IDepositToken depositToken_\n    ) external view returns (uint256 _amountToRepay, uint256 _toLiquidator, uint256 _fee);\n\n    function quoteLiquidateMax(\n        ISyntheticToken syntheticToken_,\n        address account_,\n        IDepositToken depositToken_\n    ) external view returns (uint256 _maxAmountToRepay);\n\n    function quoteLiquidateOut(\n        ISyntheticToken syntheticToken_,\n        uint256 amountToRepay_,\n        IDepositToken depositToken_\n    ) external view returns (uint256 _totalSeized, uint256 _toLiquidator, uint256 _fee);\n\n    function quoteSwapIn(\n        ISyntheticToken syntheticTokenIn_,\n        ISyntheticToken syntheticTokenOut_,\n        uint256 amountOut_\n    ) external view returns (uint256 _amountIn, uint256 _fee);\n\n    function quoteSwapOut(\n        ISyntheticToken syntheticTokenIn_,\n        ISyntheticToken syntheticTokenOut_,\n        uint256 amountIn_\n    ) external view returns (uint256 _amountOut, uint256 _fee);\n\n    function swap(\n        ISyntheticToken syntheticTokenIn_,\n        ISyntheticToken syntheticTokenOut_,\n        uint256 amountIn_\n    ) external returns (uint256 _amountOut, uint256 _fee);\n\n    function treasury() external view returns (ITreasury);\n\n    function masterOracle() external view returns (IMasterOracle);\n\n    function poolRegistry() external view returns (IPoolRegistry);\n\n    function addToDepositTokensOfAccount(address account_) external;\n\n    function removeFromDepositTokensOfAccount(address account_) external;\n\n    function addToDebtTokensOfAccount(address account_) external;\n\n    function removeFromDebtTokensOfAccount(address account_) external;\n\n    function getDepositTokensOfAccount(address account_) external view returns (address[] memory);\n\n    function getDebtTokensOfAccount(address account_) external view returns (address[] memory);\n\n    function isSwapActive() external view returns (bool);\n\n    function smartFarmingManager() external view returns (ISmartFarmingManager);\n}\n"},{"file_path":"contracts/interfaces/IPoolRegistry.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IMasterOracle} from \"./external/IMasterOracle.sol\";\nimport {IPauseable} from \"./IPauseable.sol\";\nimport {IGovernable} from \"./IGovernable.sol\";\nimport {ISyntheticToken} from \"./ISyntheticToken.sol\";\nimport {ISwapper} from \"./external/ISwapper.sol\";\nimport {IOperator} from \"./IOperator.sol\";\n\ninterface IPoolRegistry is IPauseable, IGovernable {\n    function feeCollector() external view returns (address);\n\n    function isPoolRegistered(address pool_) external view returns (bool);\n\n    function nativeTokenGateway() external view returns (address);\n\n    function getPools() external view returns (address[] memory);\n\n    function registerPool(address pool_) external;\n\n    function unregisterPool(address pool_) external;\n\n    function masterOracle() external view returns (IMasterOracle);\n\n    function updateFeeCollector(address newFeeCollector_) external;\n\n    function idOfPool(address pool_) external view returns (uint256);\n\n    function nextPoolId() external view returns (uint256);\n\n    function swapper() external view returns (ISwapper);\n\n    function doesSyntheticTokenExist(ISyntheticToken syntheticToken_) external view returns (bool _exists);\n\n    function operator() external view returns (IOperator);\n\n    function isGuardian(address) external view returns (bool);\n\n    function isBridgingActive() external view returns (bool);\n\n    function lzBaseGasLimit() external view returns (uint256);\n\n    function isDestinationChainSupported(uint16 dstChainId_) external view returns (bool);\n}\n"},{"file_path":"contracts/interfaces/IProxyOFT.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IComposableOFTCoreUpgradeable} from \"../dependencies/@layerzerolabs/solidity-examples/contracts-upgradeable/token/oft/composable/IComposableOFTCoreUpgradeable.sol\";\n\ninterface IProxyOFT is IComposableOFTCoreUpgradeable {\n    function getProxyOFTOf(uint16 chainId_) external view returns (address _proxyOFT);\n\n    function approvalRequired() external view returns (bool);\n\n    function oftFee() external view returns (uint256);\n\n    function quoteSendFromIn(uint256 amountOut_) external view returns (uint256 _amountIn, uint256 _fee);\n\n    function quoteSendFromOut(uint256 amountIn_) external view returns (uint256 _amountOut, uint256 _fee);\n\n    function updateOftFee(uint256 newOftFee_) external;\n}\n"},{"file_path":"contracts/interfaces/ISmartFarmingManager.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20} from \"../dependencies/openzeppelin/token/ERC20/IERC20.sol\";\nimport {IDepositToken} from \"./IDepositToken.sol\";\nimport {ISyntheticToken} from \"./ISyntheticToken.sol\";\n\n/**\n * @notice SmartFarmingManager interface\n */\ninterface ISmartFarmingManager {\n    function flashRepay(\n        ISyntheticToken syntheticToken_,\n        IDepositToken depositToken_,\n        uint256 withdrawAmount_,\n        uint256 swapAmountOutMin_\n    ) external returns (uint256 _withdrawn, uint256 _repaid);\n\n    function leverage(\n        IERC20 tokenIn_,\n        IDepositToken depositToken_,\n        ISyntheticToken syntheticToken_,\n        uint256 amountIn_,\n        uint256 leverage_,\n        uint256 depositAmountMin_\n    ) external returns (uint256 _deposited, uint256 _issued);\n}\n"},{"file_path":"contracts/interfaces/ISyntheticToken.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IERC20Metadata} from \"../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol\";\nimport {IPoolRegistry} from \"./IPoolRegistry.sol\";\nimport {IProxyOFT} from \"../interfaces/IProxyOFT.sol\";\n\ninterface ISyntheticToken is IERC20Metadata {\n    function isActive() external view returns (bool);\n\n    function mint(address to_, uint256 amount_) external;\n\n    function burnFor(address from_, uint256 amount) external;\n\n    function burn(uint256 amount_) external;\n\n    function burnFrom(address from_, uint256 amount_) external;\n\n    function poolRegistry() external view returns (IPoolRegistry);\n\n    function toggleIsActive() external;\n\n    function seize(address from_, address to_, uint256 amount_) external;\n\n    function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external;\n\n    function updateProxyOFT(IProxyOFT newProxyOFT_) external;\n\n    function maxTotalSupply() external view returns (uint256);\n\n    function proxyOFT() external view returns (IProxyOFT);\n\n    function amoSupply() external view returns (uint256);\n}\n"},{"file_path":"contracts/interfaces/ITreasury.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface ITreasury {\n    function pull(address to_, uint256 amount_) external;\n\n    function migrateTo(address newTreasury_) external;\n}\n"},{"file_path":"contracts/interfaces/external/IMasterOracle.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface IMasterOracle {\n    function quoteTokenToUsd(address _asset, uint256 _amount) external view returns (uint256 _amountInUsd);\n\n    function quoteUsdToToken(address _asset, uint256 _amountInUsd) external view returns (uint256 _amount);\n\n    function quote(address _assetIn, address _assetOut, uint256 _amountIn) external view returns (uint256 _amountOut);\n}\n"},{"file_path":"contracts/interfaces/external/ISwapper.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\ninterface ISwapper {\n    function swapExactInput(\n        address tokenIn_,\n        address tokenOut_,\n        uint256 amountIn_,\n        uint256 amountOutMin_,\n        address receiver_\n    ) external returns (uint256 _amountOut);\n}\n"},{"file_path":"contracts/lib/WadRayMath.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\n/**\n * @title Math library\n * @dev Provides mul and div function for wads (decimal numbers with 18 digits precision) and rays (decimals with 27 digits)\n * @dev Based on https://github.com/dapphub/ds-math/blob/master/src/math.sol\n */\nlibrary WadRayMath {\n    uint256 internal constant WAD = 1e18;\n    uint256 internal constant HALF_WAD = WAD / 2;\n\n    uint256 internal constant RAY = 1e27;\n    uint256 internal constant HALF_RAY = RAY / 2;\n\n    uint256 internal constant WAD_RAY_RATIO = 1e9;\n\n    /**\n     * @dev Multiplies two wad, rounding half up to the nearest wad\n     * @param a Wad\n     * @param b Wad\n     * @return The result of a*b, in wad\n     */\n    function wadMul(uint256 a, uint256 b) internal pure returns (uint256) {\n        if (a == 0 || b == 0) {\n            return 0;\n        }\n\n        return (a * b + HALF_WAD) / WAD;\n    }\n\n    /**\n     * @dev Divides two wad, rounding half up to the nearest wad\n     * @param a Wad\n     * @param b Wad\n     * @return The result of a/b, in wad\n     */\n    function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n        return (a * WAD + b / 2) / b;\n    }\n}\n"},{"file_path":"contracts/storage/SyntheticTokenStorage.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {IPoolRegistry} from \"../interfaces/IPoolRegistry.sol\";\nimport {IProxyOFT} from \"../interfaces/IProxyOFT.sol\";\nimport {ISyntheticToken} from \"../interfaces/ISyntheticToken.sol\";\n\nabstract contract SyntheticTokenStorageV1 is ISyntheticToken {\n    /**\n     * @notice The name of the token\n     */\n    string public override name;\n\n    /**\n     * @notice The symbol of the token\n     */\n    string public override symbol;\n\n    /**\n     * @dev The amount of tokens owned by `account`\n     */\n    mapping(address => uint256) public override balanceOf;\n\n    /**\n     * @dev The remaining number of tokens that `spender` will be\n     * allowed to spend on behalf of `owner` through {transferFrom}\n     */\n    mapping(address => mapping(address => uint256)) public override allowance;\n\n    /**\n     * @dev Amount of tokens in existence\n     */\n    uint256 public override totalSupply;\n\n    /**\n     * @notice The supply cap\n     */\n    uint256 public override maxTotalSupply;\n\n    /**\n     * @dev The Pool Registry\n     */\n    IPoolRegistry internal _poolRegistry;\n\n    /**\n     * @notice If true, disables msAsset minting globally\n     */\n    bool public override isActive;\n\n    /**\n     * @notice The decimals of the token\n     */\n    uint8 public override decimals;\n\n    /**\n     * @notice The ProxyOFT contract\n     */\n    IProxyOFT public override proxyOFT;\n\n    /**\n     * @notice Track amount received cross-chain\n     */\n    uint256 public totalBridgedIn;\n\n    /**\n     * @notice Track amount sent cross-chain\n     */\n    uint256 public totalBridgedOut;\n\n    /**\n     * @notice Maximum allowed bridged-in (mint-related) supply\n     */\n    uint256 public maxBridgedInSupply;\n\n    /**\n     * @notice Maximum allowed bridged-out (burn-related) supply\n     */\n    uint256 public maxBridgedOutSupply;\n}\n\nabstract contract SyntheticTokenStorageV2 is SyntheticTokenStorageV1 {\n    /**\n     * @notice Automated Market Operator, it can be a contract, safe or EOA\n     * @dev Should be the AMO contract. `amoSupply` is keyed on this address, so pointing it at an\n     * account that also holds synthetic tokens it did not mint lets an ordinary burn retire AMO\n     * issuance credit and free `maxAmoSupply` headroom\n     */\n    address public amo;\n\n    /**\n     * @notice Maximum Synth AMO can mint. It can be updated by admin/governor.\n     */\n    uint256 public maxAmoSupply;\n\n    /**\n     * @notice Synth minted by AMO so far. It will be reduced when Synths are burnt by AMO.\n     */\n    uint256 public amoSupply;\n}\n"},{"file_path":"contracts/utils/SynthContext.sol","source_code":"// SPDX-License-Identifier: MIT\n\npragma solidity 0.8.24;\n\nimport {Context} from \"../dependencies/openzeppelin/utils/Context.sol\";\nimport {IOperator} from \"../interfaces/IOperator.sol\";\nimport {IPoolRegistry} from \"../interfaces/IPoolRegistry.sol\";\n\nabstract contract SynthContext is Context {\n    /// @notice Get pool registry contract\n    function poolRegistry() public view virtual returns (IPoolRegistry);\n\n    /// @inheritdoc Context\n    function _msgSender() internal view virtual override returns (address) {\n        IPoolRegistry _poolRegistry = poolRegistry();\n        if (address(_poolRegistry) != address(0)) {\n            IOperator _operator = _poolRegistry.operator();\n            if (msg.sender == address(_operator)) {\n                return _operator.getActualMsgSender();\n            }\n        }\n\n        return msg.sender;\n    }\n}\n"}],"certified":false,"conflicting_implementations":null,"abi":[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressIsNull","type":"error"},{"inputs":[],"name":"AmountExceedsAllowance","type":"error"},{"inputs":[],"name":"ApproveFromTheZeroAddress","type":"error"},{"inputs":[],"name":"ApproveToTheZeroAddress","type":"error"},{"inputs":[],"name":"BurnAmountExceedsBalance","type":"error"},{"inputs":[],"name":"BurnFromTheZeroAddress","type":"error"},{"inputs":[],"name":"DecimalsIsNull","type":"error"},{"inputs":[],"name":"DecreasedAllowanceBelowZero","type":"error"},{"inputs":[],"name":"MintToTheZeroAddress","type":"error"},{"inputs":[],"name":"NameIsNull","type":"error"},{"inputs":[],"name":"NewValueIsSameAsCurrent","type":"error"},{"inputs":[],"name":"PoolRegistryIsNull","type":"error"},{"inputs":[],"name":"SenderCanNotBurn","type":"error"},{"inputs":[],"name":"SenderCanNotMint","type":"error"},{"inputs":[],"name":"SenderCanNotSeize","type":"error"},{"inputs":[],"name":"SenderIsNotGovernor","type":"error"},{"inputs":[],"name":"SurpassMaxAmoSupply","type":"error"},{"inputs":[],"name":"SurpassMaxBridgingSupply","type":"error"},{"inputs":[],"name":"SurpassMaxSynthSupply","type":"error"},{"inputs":[],"name":"SymbolIsNull","type":"error"},{"inputs":[],"name":"SyntheticIsInactive","type":"error"},{"inputs":[],"name":"TransferAmountExceedsBalance","type":"error"},{"inputs":[],"name":"TransferFromTheZeroAddress","type":"error"},{"inputs":[],"name":"TransferToTheZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldAmo","type":"address"},{"indexed":false,"internalType":"address","name":"newAmo","type":"address"}],"name":"AmoUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxAmoSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxAmoSupply","type":"uint256"}],"name":"MaxAmoSupplyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxBridgedInSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxBridgedInSupply","type":"uint256"}],"name":"MaxBridgedInSupplyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxBridgedOutSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxBridgedOutSupply","type":"uint256"}],"name":"MaxBridgedOutSupplyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxTotalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxTotalSupply","type":"uint256"}],"name":"MaxTotalSupplyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IProxyOFT","name":"oldProxyOFT","type":"address"},{"indexed":false,"internalType":"contract IProxyOFT","name":"newProxyOFT","type":"address"}],"name":"ProxyOFTUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"newActive","type":"bool"}],"name":"SyntheticTokenActiveUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"amo","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"amoSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridgedInSupply","outputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bridgedOutSupply","outputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"burnFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"subtractedValue_","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender_","type":"address"},{"internalType":"uint256","name":"addedValue_","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"uint8","name":"decimals_","type":"uint8"},{"internalType":"contract IPoolRegistry","name":"poolRegistry_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAmoSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBridgedInSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBridgedOutSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolRegistry","outputs":[{"internalType":"contract IPoolRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxyOFT","outputs":[{"internalType":"contract IProxyOFT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"seize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleIsActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalBridgedIn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBridgedOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAmo_","type":"address"}],"name":"updateAmo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxAmoSupply_","type":"uint256"}],"name":"updateMaxAmoSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxBridgedInSupply_","type":"uint256"}],"name":"updateMaxBridgedInSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxBridgedOutSupply_","type":"uint256"}],"name":"updateMaxBridgedOutSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxTotalSupply_","type":"uint256"}],"name":"updateMaxTotalSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IProxyOFT","name":"newProxyOFT_","type":"address"}],"name":"updateProxyOFT","outputs":[],"stateMutability":"nonpayable","type":"function"}],"is_changed_bytecode":false,"is_partially_verified":false,"constructor_args":null}