Sepolia Testnet

Token

Synthr syAAPL (SyAAPL)
ERC-20

Overview

Max Total Supply

45,168.323452539259427898 SyAAPL

Holders

2,605

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
0 SyAAPL
0x0000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0xFD23Be2e...961C92f7E
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
MultiCollateralSynthLightChain

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
london EvmVersion, MIT license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 17 : MultiCollateralSynthLightChain.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
// Inheritance
import "./Synth.sol";

contract MultiCollateralSynthLightChain is Synth {
    // bytes32 public constant CONTRACT_NAME = "MultiCollateralSynth";

    /* ========== CONSTRUCTOR ========== */

    constructor(
        TokenStateLightChain _tokenState,
        string memory _tokenName,
        string memory _tokenSymbol,
        address _owner,
        bytes32 _currencyKey,
        address _resolver
    ) Synth(_tokenState, _tokenName, _tokenSymbol, _owner, _currencyKey, _resolver) {}

    /* ========== VIEWS ======================= */

    /* ========== MUTATIVE FUNCTIONS ========== */

    /**
     * @notice Function that allows multi Collateral to issue a certain number of synths from an account.
     * @param account Account to issue synths to
     * @param amount Number of synths
     */
    function issue(address account, uint256 amount) external override onlyInternalContracts {
        super._internalIssue(account, amount);
    }

    /**
     * @notice Function that allows multi Collateral to burn a certain number of synths from an account.
     * @param account Account to burn synths from
     * @param amount Number of synths
     */
    function burn(address account, uint256 amount) external override onlyInternalContracts {
        super._internalBurn(account, amount);
    }

    /* ========== MODIFIERS ========== */

    // overriding modifier from super to add more internal contracts and checks
    function _isInternalContract(address account) internal view override returns (bool) {
        return super._isInternalContract(account);
        // || wrapperFactory().isWrapper(account);
        //  || (account == address(etherWrapper()))
    }
}

File 2 of 17 : SafeMath.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");

        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        uint256 c = a - b;

        return c;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
        if (a == 0) {
            return 0;
        }

        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");

        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers. Reverts on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        // Solidity only automatically asserts when dividing by 0
        require(b > 0, "SafeMath: division by zero");
        uint256 c = a / b;
        // assert(a == b * c + a % b); // There is no case in which this doesn't hold

        return c;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * Reverts when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b != 0, "SafeMath: modulo by zero");
        return a % b;
    }
}

File 3 of 17 : IAddressResolver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IAddressResolver {
    function getAddress(bytes32 name) external view returns (address);

    function getSynth(bytes32 key) external view returns (address);

    function getAvailableBridge(bytes32 bridgeName) external view returns (address);

    function getBridgeList() external view returns (bytes32[] memory);

    function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address);
}

File 4 of 17 : IERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IERC20 {
    // ERC20 Optional Views
    function name() external view returns (string memory);

    function symbol() external view returns (string memory);

    function decimals() external view returns (uint8);

    // Views
    function totalSupply() external view returns (uint256);

    function balanceOf(address owner) external view returns (uint256);

    function allowance(address owner, address spender) external view returns (uint256);

    // Mutative functions
    function transfer(address to, uint256 value) external returns (bool);

    function approve(address spender, uint256 value) external returns (bool);

    function transferFrom(address from, address to, uint256 value) external returns (bool);

    // Events
    event Transfer(address indexed from, address indexed to, uint256 value);

    event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 5 of 17 : IExchanger.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IExchanger {
    struct ExchangeEntrySettlement {
        bytes32 src;
        uint256 amount;
        bytes32 dest;
        uint256 reclaim;
        uint256 rebate;
        uint256 srcRoundIdAtPeriodEnd;
        uint256 destRoundIdAtPeriodEnd;
        uint256 timestamp;
    }

    struct ExchangeEntry {
        uint256 sourceRate;
        uint256 destinationRate;
        uint256 destinationAmount;
        uint256 exchangeFeeRate;
        uint256 exchangeDynamicFeeRate;
        uint256 roundIdForSrc;
        uint256 roundIdForDest;
    }

    struct ExchangeArgs {
        address fromAccount;
        address destAccount;
        bytes32 sourceCurrencyKey;
        bytes32 destCurrencyKey;
        uint256 sourceAmount;
        uint256 destAmount;
        uint256 fee;
        uint256 reclaimed;
        uint256 refunded;
        uint16 destChainId;
        bool erc20Payment;
    }

    // Views
    function calculateAmountAfterSettlement(
        address from,
        bytes32 currencyKey,
        uint256 amount,
        uint256 refunded
    ) external view returns (uint256 amountAfterSettlement);

    function isSynthRateInvalid(bytes32 currencyKey) external view returns (bool);

    function maxSecsLeftInWaitingPeriod(address account, bytes32 currencyKey) external view returns (uint256);

    function settlementOwing(
        address account,
        bytes32 currencyKey
    ) external view returns (uint256 reclaimAmount, uint256 rebateAmount, uint256 numEntries);

    // function hasWaitingPeriodOrSettlementOwing(address account, bytes32 currencyKey) external view returns (bool);

    function feeRateForExchange(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view returns (uint256);

    function dynamicFeeRateForExchange(
        bytes32 sourceCurrencyKey,
        bytes32 destinationCurrencyKey
    ) external view returns (uint256 feeRate, bool tooVolatile);

    function getAmountsForExchange(
        uint256 sourceAmount,
        bytes32 sourceCurrencyKey,
        bytes32 destinationCurrencyKey
    ) external view returns (uint256 amountReceived, uint256 fee, uint256 exchangeFeeRate);

    // function priceDeviationThresholdFactor() external view returns (uint256);

    // function waitingPeriodSecs() external view returns (uint256);

    // function lastExchangeRate(bytes32 currencyKey) external view returns (uint256);

    // Mutative functions
    function exchange(ExchangeArgs calldata args, bytes32 bridgeName) external payable returns (uint256 amountReceived);

    function exchangeAtomically(
        uint256 minAmount,
        ExchangeArgs calldata args,
        bytes32 bridgeName
    ) external payable returns (uint256 amountReceived);

    function settle(address from, bytes32 currencyKey) external returns (uint256 reclaimed, uint256 refunded, uint256 numEntries);

    function suspendSynthWithInvalidRate(bytes32 currencyKey) external;

    function updateDestinationForExchange(address recipient, bytes32 destinationKey, uint256 destinationAmount) external;
}

File 6 of 17 : IIssuer.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../interfaces/ISynth.sol";

interface IIssuer {
    // Views

    function allNetworksDebtInfo() external view returns (uint256 debt, uint256 sharesSupply);

    function availableCurrencyKeys() external view returns (bytes32[] memory);

    function availableSynthCount() external view returns (uint256);

    function availableSynths(uint256 index) external view returns (ISynth);

    function canBurnSynths(address account) external view returns (bool);

    function collateral(address account) external view returns (uint256);

    function collateralisationRatio(address issuer) external view returns (uint256);

    function collateralisationRatioAndAnyRatesInvalid(
        address _issuer
    ) external view returns (uint256 cratio, bool anyRateIsInvalid);

    function debtBalanceOf(address issuer) external view returns (uint256 debtBalance);

    function issuanceRatio() external view returns (uint256);

    function lastIssueEvent(address account) external view returns (uint256);

    function maxIssuableSynths(address issuer) external view returns (uint256 maxIssuable);

    function minimumStakeTime() external view returns (uint256);

    function remainingIssuableSynths(
        address issuer
    ) external view returns (uint256 maxIssuable, uint256 alreadyIssued, uint256 totalSystemDebt);

    function synths(bytes32 currencyKey) external view returns (ISynth);

    function getSynths(bytes32[] calldata currencyKeys) external view returns (ISynth[] memory);

    function synthsByAddress(address synthAddress) external view returns (bytes32);

    function totalIssuedSynths(bytes32 currencyKey) external view returns (uint256);

    function checkFreeCollateral(
        address _issuer,
        bytes32 _collateralKey,
        uint16 _chainId
    ) external view returns (uint256 withdrawableSynthr);

    function issueSynths(
        address from,
        uint256 amount,
        uint256 destChainId
    ) external returns (uint256 synthAmount, uint256 debtShare);

    function issueMaxSynths(address from, uint256 destChainId) external returns (uint256 synthAmount, uint256 debtShare);

    function burnSynths(
        address from,
        bytes32 synthKey,
        uint256 amount
    ) external returns (uint256 synthAmount, uint256 debtShare, uint256 reclaimed, uint256 refunded);

    function burnSynthsToTarget(
        address from,
        bytes32 synthKey
    ) external returns (uint256 synthAmount, uint256 debtShare, uint256 reclaimed, uint256 refunded);

    function burnForRedemption(address deprecatedSynthProxy, address account, uint256 balance) external;

    function burnSynthsWithoutDebt(bytes32 currencyKey, address from, uint amount) external returns (uint256 burnAmount);

    function synthIssueFromSynthrSwap(address _account, bytes32 _synthKey, uint256 _synthAmount) external;

    function liquidateAccount(
        address account,
        bytes32 collateralKey,
        uint16 chainId,
        bool isSelfLiquidation
    ) external returns (uint256 totalRedeemed, uint256 amountToLiquidate, uint256 sharesToRemove);

    function destIssue(address _account, bytes32 _synthKey, uint256 _synthAmount) external;

    function destBurn(address _account, bytes32 _synthKey, uint256 _synthAmount) external returns (uint256);

    function transferMargin(address account, uint256 marginDelta) external returns (uint256);

    function destTransferMargin(address _account, uint256 _marginDelta, bytes32 _marketKey) external returns (bool);

    function setCurrentPeriodId(uint128 periodId) external;
}

File 7 of 17 : IOffChainExchanger.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "./IExchanger.sol";

interface IOffChainExchanger {
    // Views
    function offchainPriceMaxAge(bytes32 _currencyKey) external view returns (uint256);

    function offchainPriceMinAge(bytes32 _currencyKey) external view returns (uint256);

    function offchainPriceDivergence(bytes32 _currencyKey) external view returns (uint256);

    function feeRateForOffChainExchange(
        bytes32 sourceCurrencyKey,
        bytes32 destinationCurrencyKey
    ) external view returns (uint256);

    function getAmountsForOffChainExchangeMinusFees(
        bytes32 _sourceKey,
        bytes32 _destKey,
        uint256 _destAmount
    ) external view returns (uint256 amountReceived, uint256 fee);

    // Mutative functions
    function exchange(
        IExchanger.ExchangeArgs calldata args,
        bytes32 bridgeName,
        bytes[] calldata priceUpdateData
    ) external payable returns (uint256 amountReceived);

    function updateDestinationForExchange(address recipient, bytes32 destinationKey, uint256 destinationAmount) external;

    function exchangeForDexAggregation(
        address _account,
        bytes32 _sourceKey,
        bytes32 _destKey,
        uint256 _sourceAmount,
        bytes[] memory _priceUpdateData,
        uint16 _destChainId
    ) external payable returns (uint256 destAmount, uint256 fee);
}

File 8 of 17 : ISynth.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ISynth {
    // Views
    function balanceOf(address _account) external view returns (uint256);

    function currencyKey() external view returns (bytes32);

    function transferableSynths(address account) external view returns (uint256);

    // Mutative functions
    function transferAndSettle(address to, uint256 value) external payable returns (bool);

    function transferFromAndSettle(address from, address to, uint256 value) external payable returns (bool);

    function burn(address account, uint256 amount) external;

    function issue(address account, uint256 amount) external;
}

File 9 of 17 : ISystemStatus.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface ISystemStatus {
    struct Status {
        bool canSuspend;
        bool canResume;
    }

    struct Suspension {
        bool suspended;
        // reason is an integer code,
        // 0 => no reason, 1 => upgrading, 2+ => defined by system usage
        uint248 reason;
    }

    // Views
    function accessControl(bytes32 section, address account) external view returns (bool canSuspend, bool canResume);

    function requireSystemActive() external view;

    function systemSuspended() external view returns (bool);

    function requireIssuanceActive() external view;

    function requireExchangeActive() external view;

    function requireFuturesActive() external view;

    function requireFuturesMarketActive(bytes32 marketKey) external view;

    function requireExchangeBetweenSynthsAllowed(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view;

    function requireSynthActive(bytes32 currencyKey) external view;

    function synthSuspended(bytes32 currencyKey) external view returns (bool);

    function requireSynthsActive(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view;

    function systemSuspension() external view returns (bool suspended, uint248 reason);

    function issuanceSuspension() external view returns (bool suspended, uint248 reason);

    function exchangeSuspension() external view returns (bool suspended, uint248 reason);

    function futuresSuspension() external view returns (bool suspended, uint248 reason);

    function synthExchangeSuspension(bytes32 currencyKey) external view returns (bool suspended, uint248 reason);

    function synthSuspension(bytes32 currencyKey) external view returns (bool suspended, uint248 reason);

    function futuresMarketSuspension(bytes32 marketKey) external view returns (bool suspended, uint248 reason);

    function getSynthExchangeSuspensions(
        bytes32[] calldata synths
    ) external view returns (bool[] memory exchangeSuspensions, uint256[] memory reasons);

    function getSynthSuspensions(
        bytes32[] calldata synths
    ) external view returns (bool[] memory suspensions, uint256[] memory reasons);

    function getFuturesMarketSuspensions(
        bytes32[] calldata marketKeys
    ) external view returns (bool[] memory suspensions, uint256[] memory reasons);

    // Restricted functions
    function suspendIssuance(uint256 reason) external;

    function suspendSynth(bytes32 currencyKey, uint256 reason) external;

    function suspendFuturesMarket(bytes32 marketKey, uint256 reason) external;

    function updateAccessControl(bytes32 section, address account, bool canSuspend, bool canResume) external;
}

File 10 of 17 : AddressResolverLightChain.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Inheritance
import "./Owned.sol";
import "../interfaces/IAddressResolver.sol";

// Internal references
import "../interfaces/IIssuer.sol";
import "./MixinResolver.sol";

contract AddressResolverLightChain is Owned, IAddressResolver {
    mapping(bytes32 => address) public repository;
    mapping(bytes32 => address) public availableBridge;
    mapping(address => bool) public isBridge;

    bytes32[] public bridgeList;

    constructor(address _owner) Owned(_owner) {}

    /* ========== RESTRICTED FUNCTIONS ========== */

    function importAddresses(bytes32[] calldata names, address[] calldata destinations) external onlyOwner {
        require(names.length == destinations.length, "Input lengths must match");

        for (uint256 i = 0; i < names.length; i++) {
            bytes32 name = names[i];
            address destination = destinations[i];
            repository[name] = destination;
            emit AddressImported(name, destination);
        }
    }

    function addAvailableBridge(bytes32 bridgeName, address bridgeAddress) external onlyOwner {
        _addAvailableBridge(bridgeName, bridgeAddress);
    }

    function removeAvailableBridge(bytes32 bridgeName) external onlyOwner {
        _removeAvailableBridge(bridgeName);
    }

    /* ========= PUBLIC FUNCTIONS ========== */

    function rebuildCaches(MixinResolver[] calldata destinations) external {
        for (uint256 i = 0; i < destinations.length; i++) {
            destinations[i].rebuildCache();
        }
    }

    /* ========== PRIVATE FUNCTIONS ========== */
    function _addAvailableBridge(bytes32 bridgeName, address bridgeAddress) private {
        if (availableBridge[bridgeName] != address(0)) {
            _removeAvailableBridge(bridgeName);
        }
        availableBridge[bridgeName] = bridgeAddress;
        isBridge[bridgeAddress] = true;
        bridgeList.push(bridgeName);
        emit AddBridge(bridgeName, bridgeAddress);
    }

    function _removeAvailableBridge(bytes32 bridgeName) private {
        require(availableBridge[bridgeName] != address(0), "The bridge no exist.");
        uint lastBridgeNumber = bridgeList.length - 1;
        for (uint ii = 0; ii <= lastBridgeNumber; ii++) {
            if (bridgeList[ii] == bridgeName) {
                bridgeList[ii] = bridgeList[lastBridgeNumber];
                bridgeList.pop();
                break;
            }
        }
        address bridgeToRemove = availableBridge[bridgeName];
        delete availableBridge[bridgeName];
        delete isBridge[bridgeToRemove];
        emit RemoveBridge(bridgeName, bridgeToRemove);
    }

    /* ========== VIEWS ========== */

    function areAddressesImported(bytes32[] calldata names, address[] calldata destinations) external view returns (bool) {
        for (uint256 i = 0; i < names.length; i++) {
            if (repository[names[i]] != destinations[i]) {
                return false;
            }
        }
        return true;
    }

    function getAddress(bytes32 name) external view returns (address) {
        return repository[name];
    }

    function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address) {
        address _foundAddress = repository[name];
        require(_foundAddress != address(0), reason);
        return _foundAddress;
    }

    function getSynth(bytes32 key) external view returns (address) {
        IIssuer issuer = IIssuer(repository["Issuer"]);
        require(address(issuer) != address(0), "Cannot find Issuer address");
        return address(issuer.synths(key));
    }

    function getAvailableBridge(bytes32 bridgeName) external view returns (address) {
        return availableBridge[bridgeName];
    }

    function getBridgeList() external view returns (bytes32[] memory) {
        return bridgeList;
    }

    /* ========== EVENTS ========== */

    event AddressImported(bytes32 name, address destination);
    event AddBridge(bytes32 indexed bridgeName, address bridgeAddress);
    event RemoveBridge(bytes32 indexed bridgeName, address bridgeAddress);
}

File 11 of 17 : ExternStateToken.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Inheritance
import "./Owned.sol";
// Libraries
import "./SafeDecimalMath.sol";

// Internal references
import "./TokenStateLightChain.sol";

contract ExternStateToken is Owned {
    using SafeMath for uint256;
    using SafeDecimalMath for uint256;

    /* ========== STATE VARIABLES ========== */

    /* Stores balances and allowances. */
    TokenStateLightChain public tokenState;

    /* Other ERC20 fields. */
    string public name;
    string public symbol;
    uint8 public decimals;

    constructor(
        TokenStateLightChain _tokenState,
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        address _owner
    ) Owned(_owner) {
        tokenState = _tokenState;

        name = _name;
        symbol = _symbol;
        decimals = _decimals;
    }

    /* ========== VIEWS ========== */

    /**
     * @notice Returns the ERC20 allowance of one party to spend on behalf of another.
     * @param owner The party authorising spending of their funds.
     * @param spender The party spending tokenOwner's funds.
     */
    function allowance(address owner, address spender) public view returns (uint256) {
        return tokenState.allowance(owner, spender);
    }

    /**
     * @notice Returns the ERC20 token balance of a given account.
     */
    function balanceOf(address account) external view returns (uint256) {
        return tokenState.balanceOf(account);
    }

    function totalSupply() external view returns (uint256) {
        return tokenState.totalSupply();
    }

    /* ========== MUTATIVE FUNCTIONS ========== */

    /**
     * @notice Set the address of the TokenState contract.
     * @dev This can be used to "pause" transfer functionality, by pointing the tokenState at 0x000..
     * as balances would be unreachable.
     */
    function setTokenState(TokenStateLightChain _tokenState) external onlyOwner {
        tokenState = _tokenState;
        emit TokenStateUpdated(address(_tokenState));
    }

    function _internalTransfer(address from, address to, uint256 value) internal virtual returns (bool) {
        /* Disallow transfers to irretrievable-addresses. */
        require(to != address(0) && to != address(this), "Cannot transfer to this address");

        // Insufficient balance will be handled by the safe subtraction.
        tokenState.setBalanceOf(from, tokenState.balanceOf(from).sub(value));
        tokenState.setBalanceOf(to, tokenState.balanceOf(to).add(value));

        // Emit a standard ERC20 transfer event
        emit Transfer(from, to, value);

        return true;
    }

    /**
     * @dev Perform an ERC20 token transfer. Designed to be called by transfer functions possessing
     * the onlyProxy or optionalProxy modifiers.
     */
    function _transferByProxy(address from, address to, uint256 value) internal returns (bool) {
        return _internalTransfer(from, to, value);
    }

    /*
     * @dev Perform an ERC20 token transferFrom. Designed to be called by transferFrom functions
     * possessing the optionalProxy or optionalProxy modifiers.
     */
    function _transferFromByProxy(address sender, address from, address to, uint256 value) internal returns (bool) {
        /* Insufficient allowance will be handled by the safe subtraction. */
        tokenState.setAllowance(from, sender, tokenState.allowance(from, sender).sub(value));
        return _internalTransfer(from, to, value);
    }

    /**
     * @notice Approves spender to transfer on the message sender's behalf.
     */
    function approve(address spender, uint256 value) public returns (bool) {
        address sender = msg.sender;

        tokenState.setAllowance(sender, spender, value);
        emit Approval(sender, spender, value);
        return true;
    }

    /* ========== EVENTS ========== */
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    event TokenStateUpdated(address newTokenState);
}

File 12 of 17 : MixinResolver.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Internal references
import "./AddressResolverLightChain.sol";

contract MixinResolver {
    AddressResolverLightChain public resolver;

    mapping(bytes32 => address) private addressCache;

    constructor(address _resolver) {
        resolver = AddressResolverLightChain(_resolver);
    }

    /* ========== INTERNAL FUNCTIONS ========== */

    function combineArrays(bytes32[] memory first, bytes32[] memory second) internal pure returns (bytes32[] memory combination) {
        combination = new bytes32[](first.length + second.length);

        for (uint256 i = 0; i < first.length; i++) {
            combination[i] = first[i];
        }

        for (uint256 j = 0; j < second.length; j++) {
            combination[first.length + j] = second[j];
        }
    }

    /* ========== PUBLIC FUNCTIONS ========== */

    // Note: this function is public not external in order for it to be overridden and invoked via super in subclasses
    function resolverAddressesRequired() public view virtual returns (bytes32[] memory addresses) {}

    function rebuildCache() public {
        bytes32[] memory requiredAddresses = resolverAddressesRequired();
        // The resolver must call this function whenver it updates its state
        for (uint256 i = 0; i < requiredAddresses.length; i++) {
            bytes32 name = requiredAddresses[i];
            // Note: can only be invoked once the resolver has all the targets needed added
            address destination = resolver.requireAndGetAddress(
                name,
                string(abi.encodePacked("Resolver missing target: ", name))
            );
            addressCache[name] = destination;
            emit CacheUpdated(name, destination);
        }
    }

    /* ========== VIEWS ========== */

    function isResolverCached() external view returns (bool) {
        bytes32[] memory requiredAddresses = resolverAddressesRequired();
        for (uint256 i = 0; i < requiredAddresses.length; i++) {
            bytes32 name = requiredAddresses[i];
            // false if our cache is invalid or if the resolver doesn't have the required address
            if (resolver.getAddress(name) != addressCache[name] || addressCache[name] == address(0)) {
                return false;
            }
        }

        return true;
    }

    /* ========== INTERNAL FUNCTIONS ========== */

    function requireAndGetAddress(bytes32 name) internal view returns (address) {
        address _foundAddress = addressCache[name];
        require(_foundAddress != address(0), string(abi.encodePacked("Missing address: ", name)));
        return _foundAddress;
    }

    /* ========== EVENTS ========== */

    event CacheUpdated(bytes32 name, address destination);
}

File 13 of 17 : Owned.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Owned {
    address public owner;
    address public nominatedOwner;

    constructor(address _owner) {
        require(_owner != address(0), "Owner address cannot be 0");
        owner = _owner;
        emit OwnerChanged(address(0), _owner);
    }

    function nominateNewOwner(address _owner) external onlyOwner {
        nominatedOwner = _owner;
        emit OwnerNominated(_owner);
    }

    function acceptOwnership() external {
        require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership");
        emit OwnerChanged(owner, nominatedOwner);
        owner = nominatedOwner;
        nominatedOwner = address(0);
    }

    modifier onlyOwner() {
        _onlyOwner();
        _;
    }

    function _onlyOwner() private view {
        require(msg.sender == owner, "Only the contract owner may perform this action");
    }

    event OwnerNominated(address newOwner);
    event OwnerChanged(address oldOwner, address newOwner);
}

File 14 of 17 : SafeDecimalMath.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Libraries
// import "openzeppelin-solidity-2.3.0/contracts/math/SafeMath.sol";
import "../externals/openzeppelin/SafeMath.sol";

library SafeDecimalMath {
    using SafeMath for uint256;

    /* Number of decimal places in the representations. */
    uint8 public constant decimals = 18;
    uint8 public constant highPrecisionDecimals = 27;

    /* The number representing 1.0. */
    uint256 public constant UNIT = 10 ** uint256(decimals);

    /* The number representing 1.0 for higher fidelity numbers. */
    uint256 public constant PRECISE_UNIT = 10 ** uint256(highPrecisionDecimals);
    uint256 private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = 10 ** uint256(highPrecisionDecimals - decimals);

    /**
     * @return Provides an interface to UNIT.
     */
    function unit() external pure returns (uint256) {
        return UNIT;
    }

    /**
     * @return Provides an interface to PRECISE_UNIT.
     */
    function preciseUnit() external pure returns (uint256) {
        return PRECISE_UNIT;
    }

    /**
     * @return The result of multiplying x and y, interpreting the operands as fixed-point
     * decimals.
     *
     * @dev A unit factor is divided out after the product of x and y is evaluated,
     * so that product must be less than 2**256. As this is an integer division,
     * the internal division always rounds down. This helps save on gas. Rounding
     * is more expensive on gas.
     */
    function multiplyDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
        /* Divide by UNIT to remove the extra factor introduced by the product. */
        return x.mul(y) / UNIT;
    }

    /**
     * @return The result of safely multiplying x and y, interpreting the operands
     * as fixed-point decimals of the specified precision unit.
     *
     * @dev The operands should be in the form of a the specified unit factor which will be
     * divided out after the product of x and y is evaluated, so that product must be
     * less than 2**256.
     *
     * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
     * Rounding is useful when you need to retain fidelity for small decimal numbers
     * (eg. small fractions or percentages).
     */
    function _multiplyDecimalRound(uint256 x, uint256 y, uint256 precisionUnit) private pure returns (uint256) {
        /* Divide by UNIT to remove the extra factor introduced by the product. */
        uint256 quotientTimesTen = x.mul(y) / (precisionUnit / 10);

        if (quotientTimesTen % 10 >= 5) {
            quotientTimesTen += 10;
        }

        return quotientTimesTen / 10;
    }

    /**
     * @return The result of safely multiplying x and y, interpreting the operands
     * as fixed-point decimals of a precise unit.
     *
     * @dev The operands should be in the precise unit factor which will be
     * divided out after the product of x and y is evaluated, so that product must be
     * less than 2**256.
     *
     * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
     * Rounding is useful when you need to retain fidelity for small decimal numbers
     * (eg. small fractions or percentages).
     */
    function multiplyDecimalRoundPrecise(uint256 x, uint256 y) internal pure returns (uint256) {
        return _multiplyDecimalRound(x, y, PRECISE_UNIT);
    }

    /**
     * @return The result of safely multiplying x and y, interpreting the operands
     * as fixed-point decimals of a standard unit.
     *
     * @dev The operands should be in the standard unit factor which will be
     * divided out after the product of x and y is evaluated, so that product must be
     * less than 2**256.
     *
     * Unlike multiplyDecimal, this function rounds the result to the nearest increment.
     * Rounding is useful when you need to retain fidelity for small decimal numbers
     * (eg. small fractions or percentages).
     */
    function multiplyDecimalRound(uint256 x, uint256 y) internal pure returns (uint256) {
        return _multiplyDecimalRound(x, y, UNIT);
    }

    /**
     * @return The result of safely dividing x and y. The return value is a high
     * precision decimal.
     *
     * @dev y is divided after the product of x and the standard precision unit
     * is evaluated, so the product of x and UNIT must be less than 2**256. As
     * this is an integer division, the result is always rounded down.
     * This helps save on gas. Rounding is more expensive on gas.
     */
    function divideDecimal(uint256 x, uint256 y) internal pure returns (uint256) {
        /* Reintroduce the UNIT factor that will be divided out by y. */
        return x.mul(UNIT).div(y);
    }

    /**
     * @return The result of safely dividing x and y. The return value is as a rounded
     * decimal in the precision unit specified in the parameter.
     *
     * @dev y is divided after the product of x and the specified precision unit
     * is evaluated, so the product of x and the specified precision unit must
     * be less than 2**256. The result is rounded to the nearest increment.
     */
    function _divideDecimalRound(uint256 x, uint256 y, uint256 precisionUnit) private pure returns (uint256) {
        uint256 resultTimesTen = x.mul(precisionUnit * 10).div(y);

        if (resultTimesTen % 10 >= 5) {
            resultTimesTen += 10;
        }

        return resultTimesTen / 10;
    }

    /**
     * @return The result of safely dividing x and y. The return value is as a rounded
     * standard precision decimal.
     *
     * @dev y is divided after the product of x and the standard precision unit
     * is evaluated, so the product of x and the standard precision unit must
     * be less than 2**256. The result is rounded to the nearest increment.
     */
    function divideDecimalRound(uint256 x, uint256 y) internal pure returns (uint256) {
        return _divideDecimalRound(x, y, UNIT);
    }

    /**
     * @return The result of safely dividing x and y. The return value is as a rounded
     * high precision decimal.
     *
     * @dev y is divided after the product of x and the high precision unit
     * is evaluated, so the product of x and the high precision unit must
     * be less than 2**256. The result is rounded to the nearest increment.
     */
    function divideDecimalRoundPrecise(uint256 x, uint256 y) internal pure returns (uint256) {
        return _divideDecimalRound(x, y, PRECISE_UNIT);
    }

    /**
     * @dev Convert a standard decimal representation to a high precision one.
     */
    function decimalToPreciseDecimal(uint256 i) internal pure returns (uint256) {
        return i.mul(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR);
    }

    /**
     * @dev Convert a high precision decimal to a standard decimal representation.
     */
    function preciseDecimalToDecimal(uint256 i) internal pure returns (uint256) {
        uint256 quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10);

        if (quotientTimesTen % 10 >= 5) {
            quotientTimesTen += 10;
        }

        return quotientTimesTen / 10;
    }

    // Computes `a - b`, setting the value to 0 if b > a.
    function floorsub(uint256 a, uint256 b) internal pure returns (uint256) {
        return b >= a ? 0 : a - b;
    }

    /* ---------- Utilities ---------- */
    /*
     * Absolute value of the input, returned as a signed number.
     */
    function signedAbs(int256 x) internal pure returns (int256) {
        return x < 0 ? -x : x;
    }

    /*
     * Absolute value of the input, returned as an unsigned number.
     */
    function abs(int256 x) internal pure returns (uint256) {
        return uint256(signedAbs(x));
    }
}

File 15 of 17 : State.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Inheritance
import "./Owned.sol";

contract State is Owned {
    // the address of the contract that can modify variables
    // this can only be changed by the owner of this contract
    address public associatedContract;

    constructor(address _owner, address _associatedContract) Owned(_owner) {
        // This contract is abstract, and thus cannot be instantiated directly
        require(owner != address(0), "Owner must be set");

        associatedContract = _associatedContract;
        emit AssociatedContractUpdated(_associatedContract);
    }

    /* ========== SETTERS ========== */

    // Change the associated contract to a new address
    function setAssociatedContract(address _associatedContract) external onlyOwner {
        associatedContract = _associatedContract;
        emit AssociatedContractUpdated(_associatedContract);
    }

    /* ========== MODIFIERS ========== */

    modifier onlyAssociatedContract() {
        require(msg.sender == associatedContract, "Only the associated contract can perform this action");
        _;
    }

    /* ========== EVENTS ========== */

    event AssociatedContractUpdated(address associatedContract);
}

File 16 of 17 : Synth.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Inheritance
import "./Owned.sol";
import "./ExternStateToken.sol";
import "./MixinResolver.sol";
import "../interfaces/ISynth.sol";
import "../interfaces/IERC20.sol";

// Internal references
import "../interfaces/ISystemStatus.sol";
import "../interfaces/IExchanger.sol";
import "../interfaces/IOffChainExchanger.sol";
import "../interfaces/IIssuer.sol";
import "./SafeDecimalMath.sol";

contract Synth is Owned, ExternStateToken, MixinResolver {
    using SafeMath for uint256;
    using SafeDecimalMath for uint256;

    bytes32 public constant CONTRACT_NAME = "Synth";

    /* ========== STATE VARIABLES ========== */

    // Currency key which identifies this Synth to the Synthr system
    bytes32 public currencyKey;
    address private syAggregator;

    uint8 public constant DECIMALS = 18;

    // Where fees are pooled in sUSD
    address public constant FEE_ADDRESS = 0xfeEFEEfeefEeFeefEEFEEfEeFeefEEFeeFEEFEeF;

    /* ========== ADDRESS RESOLVER CONFIGURATION ========== */

    bytes32 private constant CONTRACT_SYSTEMSTATUS = "SystemStatus";
    bytes32 private constant CONTRACT_EXCHANGER = "Exchanger";
    bytes32 private constant CONTRACT_OFF_CHAIN_EXCHANGER = "OffChainExchanger";
    bytes32 private constant CONTRACT_ISSUER = "Issuer";

    /* ========== CONSTRUCTOR ========== */

    constructor(
        TokenStateLightChain _tokenState,
        string memory _tokenName,
        string memory _tokenSymbol,
        address _owner,
        bytes32 _currencyKey,
        address _resolver
    ) ExternStateToken(_tokenState, _tokenName, _tokenSymbol, DECIMALS, _owner) MixinResolver(_resolver) {
        require(_owner != address(0), "_owner cannot be 0");

        currencyKey = _currencyKey;
    }

    /* ========== VIEWS ========== */

    // Note: use public visibility so that it can be invoked in a subclass
    function resolverAddressesRequired() public view virtual override returns (bytes32[] memory addresses) {
        addresses = new bytes32[](4);
        addresses[0] = CONTRACT_SYSTEMSTATUS;
        addresses[1] = CONTRACT_EXCHANGER;
        addresses[2] = CONTRACT_ISSUER;
        addresses[3] = CONTRACT_OFF_CHAIN_EXCHANGER;
    }

    function systemStatus() internal view returns (ISystemStatus) {
        return ISystemStatus(requireAndGetAddress(CONTRACT_SYSTEMSTATUS));
    }

    function exchanger() internal view returns (IExchanger) {
        return IExchanger(requireAndGetAddress(CONTRACT_EXCHANGER));
    }

    function offChainExchanger() internal view returns (IOffChainExchanger) {
        return IOffChainExchanger(requireAndGetAddress(CONTRACT_OFF_CHAIN_EXCHANGER));
    }

    function issuer() internal view returns (IIssuer) {
        return IIssuer(requireAndGetAddress(CONTRACT_ISSUER));
    }

    function _ensureCanTransfer(address from, uint256 value) internal view {
        require(exchanger().maxSecsLeftInWaitingPeriod(from, currencyKey) == 0, "Cannot transfer during waiting period");
        require(transferableSynths(from) >= value, "Insufficient balance after any settlement owing");
        systemStatus().requireSynthActive(currencyKey);
    }

    function transferableSynths(address account) public view returns (uint256) {
        (uint256 reclaimAmount, , ) = exchanger().settlementOwing(account, currencyKey);

        // Note: ignoring rebate amount here because a settle() is required in order to
        // allow the transfer to actually work

        uint256 balance = tokenState.balanceOf(account);

        if (reclaimAmount > balance) {
            return 0;
        } else {
            return balance.sub(reclaimAmount);
        }
    }

    /* ========== MUTATIVE FUNCTIONS ========== */
    function transfer(address to, uint256 value) public payable returns (bool) {
        _ensureCanTransfer(msg.sender, value);

        // transfers to 0x address will be burned
        if (to == address(0)) {
            return _internalBurn(msg.sender, value);
        }

        return _internalTransfer(msg.sender, to, value);
    }

    function transferAndSettle(address to, uint256 value) public payable returns (bool) {
        // Exchanger.settle ensures synth is active
        (, , uint256 numEntriesSettled) = exchanger().settle(msg.sender, currencyKey);

        // Save gas instead of calling transferableSynths
        uint256 balanceAfter = value;

        if (numEntriesSettled > 0) {
            balanceAfter = tokenState.balanceOf(msg.sender);
        }

        // Reduce the value to transfer if balance is insufficient after reclaimed
        value = value > balanceAfter ? balanceAfter : value;

        return _internalTransfer(msg.sender, to, value);
    }

    function transferFrom(address from, address to, uint256 value) public payable returns (bool) {
        _ensureCanTransfer(from, value);

        return _internalTransferFrom(from, to, value);
    }

    function transferFromAndSettle(address from, address to, uint256 value) public payable returns (bool) {
        // Exchanger.settle() ensures synth is active
        (, , uint256 numEntriesSettled) = exchanger().settle(from, currencyKey);

        // Save gas instead of calling transferableSynths
        uint256 balanceAfter = value;

        if (numEntriesSettled > 0) {
            balanceAfter = tokenState.balanceOf(from);
        }

        // Reduce the value to transfer if balance is insufficient after reclaimed
        value = value >= balanceAfter ? balanceAfter : value;

        return _internalTransferFrom(from, to, value);
    }

    function issue(address account, uint256 amount) external virtual onlyInternalContracts {
        _internalIssue(account, amount);
    }

    function burn(address account, uint256 amount) external virtual onlyInternalContracts {
        _internalBurn(account, amount);
    }

    function _internalIssue(address account, uint256 amount) internal {
        tokenState.setBalanceOf(account, tokenState.balanceOf(account).add(amount));
        tokenState.setTotalSupply(tokenState.totalSupply().add(amount));
        emit Transfer(address(0), account, amount);
        // emit Issued(account, amount);
    }

    function _internalBurn(address account, uint256 amount) internal returns (bool) {
        tokenState.setBalanceOf(account, tokenState.balanceOf(account).sub(amount));
        tokenState.setTotalSupply(tokenState.totalSupply().sub(amount));
        emit Transfer(account, address(0), amount);
        // emit Burned(account, amount);

        return true;
    }

    // Allow owner to set the total supply on import.
    function setTotalSupply(uint256 amount) external onlyOwner {
        tokenState.setTotalSupply(amount);
    }

    /* ========== INTERNAL FUNCTIONS ========== */

    function _internalTransferFrom(address from, address to, uint256 value) internal returns (bool) {
        // Skip allowance update in case of infinite allowance
        if (tokenState.allowance(from, msg.sender) != type(uint256).max) {
            // Reduce the allowance by the amount we're transferring.
            // The safeSub call will handle an insufficient allowance.
            tokenState.setAllowance(from, msg.sender, tokenState.allowance(from, msg.sender).sub(value));
        }
        return super._internalTransfer(from, to, value);
    }

    function _internalTransfer(address from, address to, uint256 value) internal override returns (bool) {
        return super._internalTransfer(from, to, value);
    }

    /* ========== MODIFIERS ========== */

    function _isInternalContract(address account) internal view virtual returns (bool) {
        return account == address(exchanger()) || account == address(issuer()) || account == address(offChainExchanger());
    }

    modifier onlyInternalContracts() {
        require(_isInternalContract(msg.sender), "Only internal contracts allowed");
        _;
    }

    /* ========== EVENTS ========== */
    // event Issued(address indexed account, uint256 value);

    // event Burned(address indexed account, uint256 value);
}

File 17 of 17 : TokenStateLightChain.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

// Inheritance
import "./State.sol";

contract TokenStateLightChain is State {
    /* ERC20 fields. */
    mapping(address => uint256) public balanceOf;
    mapping(address => mapping(address => uint256)) public allowance;
    uint256 public totalSupply;

    constructor(address _owner, address _associatedContract, uint256 _totalSupply) State(_owner, _associatedContract) {}

    /* ========== SETTERS ========== */

    /**
     * @notice Set ERC20 allowance.
     * @dev Only the associated contract may call this.
     * @param tokenOwner The authorising party.
     * @param spender The authorised party.
     * @param value The total value the authorised party may spend on the
     * authorising party's behalf.
     */
    function setAllowance(address tokenOwner, address spender, uint256 value) external onlyAssociatedContract {
        allowance[tokenOwner][spender] = value;
    }

    /**
     * @notice Set the balance in a given account
     * @dev Only the associated contract may call this.
     * @param account The account whose value to set.
     * @param value The new balance of the given account.
     */
    function setBalanceOf(address account, uint256 value) external onlyAssociatedContract {
        balanceOf[account] = value;
    }

    function setTotalSupply(uint256 _amount) external onlyAssociatedContract {
        totalSupply = _amount;
    }
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract ABI

[{"inputs":[{"internalType":"contract TokenStateLightChain","name":"_tokenState","type":"address"},{"internalType":"string","name":"_tokenName","type":"string"},{"internalType":"string","name":"_tokenSymbol","type":"string"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"bytes32","name":"_currencyKey","type":"bytes32"},{"internalType":"address","name":"_resolver","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"CacheUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newTokenState","type":"address"}],"name":"TokenStateUpdated","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":"CONTRACT_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currencyKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isResolverCached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"issue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebuildCache","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resolver","outputs":[{"internalType":"contract AddressResolverLightChain","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"resolverAddressesRequired","outputs":[{"internalType":"bytes32[]","name":"addresses","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract TokenStateLightChain","name":"_tokenState","type":"address"}],"name":"setTokenState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setTotalSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenState","outputs":[{"internalType":"contract TokenStateLightChain","name":"","type":"address"}],"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":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferAndSettle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFromAndSettle","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"transferableSynths","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b506040516200254f3803806200254f833981016040819052620000349162000353565b85858585858580868686601287806001600160a01b0381166200009e5760405162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f7420626520300000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03831690811782556040805192835260208301919091527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a150600280546001600160a01b0319166001600160a01b038716179055835162000126906003906020870190620001c7565b5082516200013c906004906020860190620001c7565b50506005805460ff929092166001600160a81b0319909216919091176101006001600160a01b03968716021790555050508316620001b25760405162461bcd60e51b815260206004820152601260248201527105f6f776e65722063616e6e6f7420626520360741b604482015260640162000095565b50600755506200044498505050505050505050565b828054620001d59062000407565b90600052602060002090601f016020900481019282620001f9576000855562000244565b82601f106200021457805160ff191683800117855562000244565b8280016001018555821562000244579182015b828111156200024457825182559160200191906001019062000227565b506200025292915062000256565b5090565b5b8082111562000252576000815560010162000257565b6001600160a01b03811681146200028357600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620002ae57600080fd5b81516001600160401b0380821115620002cb57620002cb62000286565b604051601f8301601f19908116603f01168101908282118183101715620002f657620002f662000286565b816040528381526020925086838588010111156200031357600080fd5b600091505b8382101562000337578582018301518183018401529082019062000318565b83821115620003495760008385830101525b9695505050505050565b60008060008060008060c087890312156200036d57600080fd5b86516200037a816200026d565b60208801519096506001600160401b03808211156200039857600080fd5b620003a68a838b016200029c565b96506040890151915080821115620003bd57600080fd5b50620003cc89828a016200029c565b9450506060870151620003df816200026d565b608088015160a08901519194509250620003f9816200026d565b809150509295509295509295565b600181811c908216806200041c57607f821691505b602082108114156200043e57634e487b7160e01b600052602260045260246000fd5b50919050565b6120fb80620004546000396000f3fe6080604052600436106101c25760003560e01c8063867904b4116100f7578063b014c3a311610095578063e90dd9e211610064578063e90dd9e2146104b5578063eb1edd61146104d5578063f7ea7a3d146104fd578063ffff51d61461051d57600080fd5b8063b014c3a314610459578063dbd06c851461046c578063dd62ed3e14610482578063e73cced3146104a257600080fd5b806395d89b41116100d157806395d89b41146103f15780639dc29fac146104065780639f76980714610426578063a9059cbb1461044657600080fd5b8063867904b41461038f578063899ffef4146103af5780638da5cb5b146103d157600080fd5b80632e0f262511610164578063614d08f81161013e578063614d08f81461032957806370a0823114610345578063741853601461036557806379ba50971461037a57600080fd5b80632e0f2625146102c8578063313ce567146102ef57806353a47bb71461030957600080fd5b80631627540c116101a05780631627540c1461025b57806318160ddd1461027d57806323b872dd146102a05780632af64bd3146102b357600080fd5b806304f3bcec146101c757806306fdde0314610209578063095ea7b31461022b575b600080fd5b3480156101d357600080fd5b506005546101ec9061010090046001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021557600080fd5b5061021e61053d565b6040516102009190611e4c565b34801561023757600080fd5b5061024b610246366004611e77565b6105cb565b6040519015158152602001610200565b34801561026757600080fd5b5061027b610276366004611ea3565b610696565b005b34801561028957600080fd5b506102926106f3565b604051908152602001610200565b61024b6102ae366004611ec0565b610775565b3480156102bf57600080fd5b5061024b610794565b3480156102d457600080fd5b506102dd601281565b60405160ff9091168152602001610200565b3480156102fb57600080fd5b506005546102dd9060ff1681565b34801561031557600080fd5b506001546101ec906001600160a01b031681565b34801561033557600080fd5b50610292640a6f2dce8d60db1b81565b34801561035157600080fd5b50610292610360366004611ea3565b6108b9565b34801561037157600080fd5b5061027b610937565b34801561038657600080fd5b5061027b610acb565b34801561039b57600080fd5b5061027b6103aa366004611e77565b610bba565b3480156103bb57600080fd5b506103c4610c19565b6040516102009190611f01565b3480156103dd57600080fd5b506000546101ec906001600160a01b031681565b3480156103fd57600080fd5b5061021e610cf7565b34801561041257600080fd5b5061027b610421366004611e77565b610d04565b34801561043257600080fd5b5061027b610441366004611ea3565b610d68565b61024b610454366004611e77565b610dbe565b61024b610467366004611e77565b610dfb565b34801561047857600080fd5b5061029260075481565b34801561048e57600080fd5b5061029261049d366004611f45565b610f3b565b61024b6104b0366004611ec0565b610fc1565b3480156104c157600080fd5b506002546101ec906001600160a01b031681565b3480156104e157600080fd5b506101ec73feefeefeefeefeefeefeefeefeefeefeefeefeef81565b34801561050957600080fd5b5061027b610518366004611f7e565b611105565b34801561052957600080fd5b50610292610538366004611ea3565b61116e565b6003805461054a90611f97565b80601f016020809104026020016040519081016040528092919081815260200182805461057690611f97565b80156105c35780601f10610598576101008083540402835291602001916105c3565b820191906000526020600020905b8154815290600101906020018083116105a657829003601f168201915b505050505081565b600254604051633691826360e21b815233600482018190526001600160a01b03858116602484015260448301859052600093919291169063da46098c90606401600060405180830381600087803b15801561062557600080fd5b505af1158015610639573d6000803e3d6000fd5b50505050836001600160a01b0316816001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258560405161068291815260200190565b60405180910390a360019150505b92915050565b61069e6112a0565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020015b60405180910390a150565b600254604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561073857600080fd5b505afa15801561074c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107709190611fd2565b905090565b60006107818483611314565b61078c8484846114d6565b949350505050565b60008061079f610c19565b905060005b81518110156108b05760008282815181106107c1576107c1611feb565b602090810291909101810151600081815260069092526040918290205460055492516321f8a72160e01b8152600481018390529193506001600160a01b0390811692610100900416906321f8a7219060240160206040518083038186803b15801561082b57600080fd5b505afa15801561083f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108639190612001565b6001600160a01b031614158061088e57506000818152600660205260409020546001600160a01b0316155b1561089d576000935050505090565b50806108a881612034565b9150506107a4565b50600191505090565b6002546040516370a0823160e01b81526001600160a01b03838116600483015260009216906370a082319060240160206040518083038186803b1580156108ff57600080fd5b505afa158015610913573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106909190611fd2565b6000610941610c19565b905060005b8151811015610ac757600082828151811061096357610963611feb565b602002602001015190506000600560019054906101000a90046001600160a01b03166001600160a01b031663dacb2d0183846040516020016109d191907f5265736f6c766572206d697373696e67207461726765743a20000000000000008152601981019190915260390190565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016109fd92919061204f565b60206040518083038186803b158015610a1557600080fd5b505afa158015610a29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4d9190612001565b60008381526006602090815260409182902080546001600160a01b0319166001600160a01b0385169081179091558251868152918201529192507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68910160405180910390a150508080610abf90612034565b915050610946565b5050565b6001546001600160a01b03163314610b485760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b60648201526084015b60405180910390fd5b600054600154604080516001600160a01b0393841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b610bc333611673565b610c0f5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920696e7465726e616c20636f6e74726163747320616c6c6f776564006044820152606401610b3f565b610ac7828261167e565b60408051600480825260a08201909252606091602082016080803683370190505090506b53797374656d53746174757360a01b81600081518110610c5f57610c5f611feb565b6020026020010181815250506822bc31b430b733b2b960b91b81600181518110610c8b57610c8b611feb565b6020026020010181815250506524b9b9bab2b960d11b81600281518110610cb457610cb4611feb565b6020026020010181815250507027b33321b430b4b722bc31b430b733b2b960791b81600381518110610ce857610ce8611feb565b60200260200101818152505090565b6004805461054a90611f97565b610d0d33611673565b610d595760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920696e7465726e616c20636f6e74726163747320616c6c6f776564006044820152606401610b3f565b610d638282611858565b505050565b610d706112a0565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fa538c4dcfe9fb148efee2952bafe34982d2d07d5fbb38ae5b44abf659a46bfd8906020016106e8565b6000610dca3383611314565b6001600160a01b038316610de957610de23383611858565b9050610690565b610df43384846119e6565b9392505050565b600080610e066119f3565b6007546040516306c5a00b60e21b815233600482015260248101919091526001600160a01b039190911690631b16802c90604401606060405180830381600087803b158015610e5457600080fd5b505af1158015610e68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8c9190612068565b9250849150508115610f16576002546040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610edb57600080fd5b505afa158015610eef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f139190611fd2565b90505b808411610f235783610f25565b805b9350610f323386866119e6565b95945050505050565b600254604051636eb1769f60e11b81526001600160a01b0384811660048301528381166024830152600092169063dd62ed3e9060440160206040518083038186803b158015610f8957600080fd5b505afa158015610f9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df49190611fd2565b600080610fcc6119f3565b6007546040516306c5a00b60e21b81526001600160a01b0388811660048301526024820192909252911690631b16802c90604401606060405180830381600087803b15801561101a57600080fd5b505af115801561102e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110529190612068565b92508491505081156110de576002546040516370a0823160e01b81526001600160a01b038881166004830152909116906370a082319060240160206040518083038186803b1580156110a357600080fd5b505afa1580156110b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110db9190611fd2565b90505b808410156110ec57836110ee565b805b93506110fb8686866114d6565b9695505050505050565b61110d6112a0565b60025460405163f7ea7a3d60e01b8152600481018390526001600160a01b039091169063f7ea7a3d90602401600060405180830381600087803b15801561115357600080fd5b505af1158015611167573d6000803e3d6000fd5b5050505050565b6000806111796119f3565b6007546040516319d5c66560e01b81526001600160a01b03868116600483015260248201929092529116906319d5c6659060440160606040518083038186803b1580156111c557600080fd5b505afa1580156111d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fd9190612068565b50506002546040516370a0823160e01b81526001600160a01b038681166004830152929350600092909116906370a082319060240160206040518083038186803b15801561124a57600080fd5b505afa15801561125e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112829190611fd2565b905080821115611296575060009392505050565b61078c8183611a0a565b6000546001600160a01b031633146113125760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610b3f565b565b61131c6119f3565b6007546040516301670a7b60e21b81526001600160a01b038581166004830152602482019290925291169063059c29ec9060440160206040518083038186803b15801561136857600080fd5b505afa15801561137c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a09190611fd2565b156113fb5760405162461bcd60e51b815260206004820152602560248201527f43616e6e6f74207472616e7366657220647572696e672077616974696e672070604482015264195c9a5bd960da1b6064820152608401610b3f565b806114058361116e565b101561146b5760405162461bcd60e51b815260206004820152602f60248201527f496e73756666696369656e742062616c616e636520616674657220616e79207360448201526e6574746c656d656e74206f77696e6760881b6064820152608401610b3f565b611473611a68565b6001600160a01b03166342a28e216007546040518263ffffffff1660e01b81526004016114a291815260200190565b60006040518083038186803b1580156114ba57600080fd5b505afa1580156114ce573d6000803e3d6000fd5b505050505050565b600254604051636eb1769f60e11b81526001600160a01b0385811660048301523360248301526000926000199291169063dd62ed3e9060440160206040518083038186803b15801561152757600080fd5b505afa15801561153b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155f9190611fd2565b1461166857600254604051636eb1769f60e11b81526001600160a01b038681166004830152336024830181905292169163da46098c91879190611600908790869063dd62ed3e906044015b60206040518083038186803b1580156115c257600080fd5b505afa1580156115d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fa9190611fd2565b90611a0a565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561164f57600080fd5b505af1158015611663573d6000803e3d6000fd5b505050505b61078c848484611a82565b600061069082611c88565b6002546040516370a0823160e01b81526001600160a01b0384811660048301529091169063b46310f690849061171290859085906370a08231906024015b60206040518083038186803b1580156116d457600080fd5b505afa1580156116e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170c9190611fd2565b90611cf1565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561175857600080fd5b505af115801561176c573d6000803e3d6000fd5b5050600254604080516318160ddd60e01b815290516001600160a01b03909216935063f7ea7a3d92506117c391859185916318160ddd91600480820192602092909190829003018186803b1580156116d457600080fd5b6040518263ffffffff1660e01b81526004016117e191815260200190565b600060405180830381600087803b1580156117fb57600080fd5b505af115801561180f573d6000803e3d6000fd5b50506040518381526001600160a01b0385169250600091507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6002546040516370a0823160e01b81526001600160a01b038481166004830152600092169063b46310f690859061189b90869085906370a08231906024016115aa565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156118e157600080fd5b505af11580156118f5573d6000803e3d6000fd5b5050600254604080516318160ddd60e01b815290516001600160a01b03909216935063f7ea7a3d925061194c91869185916318160ddd91600480820192602092909190829003018186803b1580156115c257600080fd5b6040518263ffffffff1660e01b815260040161196a91815260200190565b600060405180830381600087803b15801561198457600080fd5b505af1158015611998573d6000803e3d6000fd5b5050604051848152600092506001600160a01b03861691507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350600192915050565b600061078c848484611a82565b60006107706822bc31b430b733b2b960b91b611d50565b600082821115611a5c5760405162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006044820152606401610b3f565b600061078c8385612096565b60006107706b53797374656d53746174757360a01b611d50565b60006001600160a01b03831615801590611aa557506001600160a01b0383163014155b611af15760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74207472616e7366657220746f20746869732061646472657373006044820152606401610b3f565b6002546040516370a0823160e01b81526001600160a01b0386811660048301529091169063b46310f6908690611b3390869085906370a08231906024016115aa565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611b7957600080fd5b505af1158015611b8d573d6000803e3d6000fd5b50506002546040516370a0823160e01b81526001600160a01b038781166004830152909116925063b46310f691508590611bd390869085906370a08231906024016116bc565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611c1957600080fd5b505af1158015611c2d573d6000803e3d6000fd5b50505050826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c7691815260200190565b60405180910390a35060019392505050565b6000611c926119f3565b6001600160a01b0316826001600160a01b03161480611cc95750611cb4611dcc565b6001600160a01b0316826001600160a01b0316145b806106905750611cd7611de0565b6001600160a01b0316826001600160a01b03161492915050565b600080611cfe83856120ad565b905083811015610df45760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610b3f565b600081815260066020908152604080832054905170026b4b9b9b4b7339030b2323932b9b99d1607d1b92810192909252603182018490526001600160a01b0316908115159060510160405160208183030381529060405290611dc55760405162461bcd60e51b8152600401610b3f9190611e4c565b5092915050565b60006107706524b9b9bab2b960d11b611d50565b60006107707027b33321b430b4b722bc31b430b733b2b960791b611d50565b6000815180845260005b81811015611e2557602081850181015186830182015201611e09565b81811115611e37576000602083870101525b50601f01601f19169290920160200192915050565b602081526000610df46020830184611dff565b6001600160a01b0381168114611e7457600080fd5b50565b60008060408385031215611e8a57600080fd5b8235611e9581611e5f565b946020939093013593505050565b600060208284031215611eb557600080fd5b8135610df481611e5f565b600080600060608486031215611ed557600080fd5b8335611ee081611e5f565b92506020840135611ef081611e5f565b929592945050506040919091013590565b6020808252825182820181905260009190848201906040850190845b81811015611f3957835183529284019291840191600101611f1d565b50909695505050505050565b60008060408385031215611f5857600080fd5b8235611f6381611e5f565b91506020830135611f7381611e5f565b809150509250929050565b600060208284031215611f9057600080fd5b5035919050565b600181811c90821680611fab57607f821691505b60208210811415611fcc57634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215611fe457600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561201357600080fd5b8151610df481611e5f565b634e487b7160e01b600052601160045260246000fd5b60006000198214156120485761204861201e565b5060010190565b82815260406020820152600061078c6040830184611dff565b60008060006060848603121561207d57600080fd5b8351925060208401519150604084015190509250925092565b6000828210156120a8576120a861201e565b500390565b600082198211156120c0576120c061201e565b50019056fea2646970667358221220ab3d86a5fbec1420bed537e5d509897a1f23255073638c2c18175b724f76bd9b64736f6c634300080900330000000000000000000000002ddf55951341d40ec9cd8746c5e1451db75f906500000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000006f808ae3445a711ecaa4da5c8330b051541a4de0734156415800000000000000000000000000000000000000000000000000000000000000000000000000000014611eee8b9586d4af1f651682dca8e2c9daa234000000000000000000000000000000000000000000000000000000000000000d53796e746872207379415641580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000065379415641580000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106101c25760003560e01c8063867904b4116100f7578063b014c3a311610095578063e90dd9e211610064578063e90dd9e2146104b5578063eb1edd61146104d5578063f7ea7a3d146104fd578063ffff51d61461051d57600080fd5b8063b014c3a314610459578063dbd06c851461046c578063dd62ed3e14610482578063e73cced3146104a257600080fd5b806395d89b41116100d157806395d89b41146103f15780639dc29fac146104065780639f76980714610426578063a9059cbb1461044657600080fd5b8063867904b41461038f578063899ffef4146103af5780638da5cb5b146103d157600080fd5b80632e0f262511610164578063614d08f81161013e578063614d08f81461032957806370a0823114610345578063741853601461036557806379ba50971461037a57600080fd5b80632e0f2625146102c8578063313ce567146102ef57806353a47bb71461030957600080fd5b80631627540c116101a05780631627540c1461025b57806318160ddd1461027d57806323b872dd146102a05780632af64bd3146102b357600080fd5b806304f3bcec146101c757806306fdde0314610209578063095ea7b31461022b575b600080fd5b3480156101d357600080fd5b506005546101ec9061010090046001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561021557600080fd5b5061021e61053d565b6040516102009190611e4c565b34801561023757600080fd5b5061024b610246366004611e77565b6105cb565b6040519015158152602001610200565b34801561026757600080fd5b5061027b610276366004611ea3565b610696565b005b34801561028957600080fd5b506102926106f3565b604051908152602001610200565b61024b6102ae366004611ec0565b610775565b3480156102bf57600080fd5b5061024b610794565b3480156102d457600080fd5b506102dd601281565b60405160ff9091168152602001610200565b3480156102fb57600080fd5b506005546102dd9060ff1681565b34801561031557600080fd5b506001546101ec906001600160a01b031681565b34801561033557600080fd5b50610292640a6f2dce8d60db1b81565b34801561035157600080fd5b50610292610360366004611ea3565b6108b9565b34801561037157600080fd5b5061027b610937565b34801561038657600080fd5b5061027b610acb565b34801561039b57600080fd5b5061027b6103aa366004611e77565b610bba565b3480156103bb57600080fd5b506103c4610c19565b6040516102009190611f01565b3480156103dd57600080fd5b506000546101ec906001600160a01b031681565b3480156103fd57600080fd5b5061021e610cf7565b34801561041257600080fd5b5061027b610421366004611e77565b610d04565b34801561043257600080fd5b5061027b610441366004611ea3565b610d68565b61024b610454366004611e77565b610dbe565b61024b610467366004611e77565b610dfb565b34801561047857600080fd5b5061029260075481565b34801561048e57600080fd5b5061029261049d366004611f45565b610f3b565b61024b6104b0366004611ec0565b610fc1565b3480156104c157600080fd5b506002546101ec906001600160a01b031681565b3480156104e157600080fd5b506101ec73feefeefeefeefeefeefeefeefeefeefeefeefeef81565b34801561050957600080fd5b5061027b610518366004611f7e565b611105565b34801561052957600080fd5b50610292610538366004611ea3565b61116e565b6003805461054a90611f97565b80601f016020809104026020016040519081016040528092919081815260200182805461057690611f97565b80156105c35780601f10610598576101008083540402835291602001916105c3565b820191906000526020600020905b8154815290600101906020018083116105a657829003601f168201915b505050505081565b600254604051633691826360e21b815233600482018190526001600160a01b03858116602484015260448301859052600093919291169063da46098c90606401600060405180830381600087803b15801561062557600080fd5b505af1158015610639573d6000803e3d6000fd5b50505050836001600160a01b0316816001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9258560405161068291815260200190565b60405180910390a360019150505b92915050565b61069e6112a0565b600180546001600160a01b0319166001600160a01b0383169081179091556040519081527f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906020015b60405180910390a150565b600254604080516318160ddd60e01b815290516000926001600160a01b0316916318160ddd916004808301926020929190829003018186803b15801561073857600080fd5b505afa15801561074c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107709190611fd2565b905090565b60006107818483611314565b61078c8484846114d6565b949350505050565b60008061079f610c19565b905060005b81518110156108b05760008282815181106107c1576107c1611feb565b602090810291909101810151600081815260069092526040918290205460055492516321f8a72160e01b8152600481018390529193506001600160a01b0390811692610100900416906321f8a7219060240160206040518083038186803b15801561082b57600080fd5b505afa15801561083f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108639190612001565b6001600160a01b031614158061088e57506000818152600660205260409020546001600160a01b0316155b1561089d576000935050505090565b50806108a881612034565b9150506107a4565b50600191505090565b6002546040516370a0823160e01b81526001600160a01b03838116600483015260009216906370a082319060240160206040518083038186803b1580156108ff57600080fd5b505afa158015610913573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106909190611fd2565b6000610941610c19565b905060005b8151811015610ac757600082828151811061096357610963611feb565b602002602001015190506000600560019054906101000a90046001600160a01b03166001600160a01b031663dacb2d0183846040516020016109d191907f5265736f6c766572206d697373696e67207461726765743a20000000000000008152601981019190915260390190565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016109fd92919061204f565b60206040518083038186803b158015610a1557600080fd5b505afa158015610a29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a4d9190612001565b60008381526006602090815260409182902080546001600160a01b0319166001600160a01b0385169081179091558251868152918201529192507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68910160405180910390a150508080610abf90612034565b915050610946565b5050565b6001546001600160a01b03163314610b485760405162461bcd60e51b815260206004820152603560248201527f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7560448201527402063616e20616363657074206f776e65727368697605c1b60648201526084015b60405180910390fd5b600054600154604080516001600160a01b0393841681529290911660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b610bc333611673565b610c0f5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920696e7465726e616c20636f6e74726163747320616c6c6f776564006044820152606401610b3f565b610ac7828261167e565b60408051600480825260a08201909252606091602082016080803683370190505090506b53797374656d53746174757360a01b81600081518110610c5f57610c5f611feb565b6020026020010181815250506822bc31b430b733b2b960b91b81600181518110610c8b57610c8b611feb565b6020026020010181815250506524b9b9bab2b960d11b81600281518110610cb457610cb4611feb565b6020026020010181815250507027b33321b430b4b722bc31b430b733b2b960791b81600381518110610ce857610ce8611feb565b60200260200101818152505090565b6004805461054a90611f97565b610d0d33611673565b610d595760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920696e7465726e616c20636f6e74726163747320616c6c6f776564006044820152606401610b3f565b610d638282611858565b505050565b610d706112a0565b600280546001600160a01b0319166001600160a01b0383169081179091556040519081527fa538c4dcfe9fb148efee2952bafe34982d2d07d5fbb38ae5b44abf659a46bfd8906020016106e8565b6000610dca3383611314565b6001600160a01b038316610de957610de23383611858565b9050610690565b610df43384846119e6565b9392505050565b600080610e066119f3565b6007546040516306c5a00b60e21b815233600482015260248101919091526001600160a01b039190911690631b16802c90604401606060405180830381600087803b158015610e5457600080fd5b505af1158015610e68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e8c9190612068565b9250849150508115610f16576002546040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b158015610edb57600080fd5b505afa158015610eef573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f139190611fd2565b90505b808411610f235783610f25565b805b9350610f323386866119e6565b95945050505050565b600254604051636eb1769f60e11b81526001600160a01b0384811660048301528381166024830152600092169063dd62ed3e9060440160206040518083038186803b158015610f8957600080fd5b505afa158015610f9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df49190611fd2565b600080610fcc6119f3565b6007546040516306c5a00b60e21b81526001600160a01b0388811660048301526024820192909252911690631b16802c90604401606060405180830381600087803b15801561101a57600080fd5b505af115801561102e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110529190612068565b92508491505081156110de576002546040516370a0823160e01b81526001600160a01b038881166004830152909116906370a082319060240160206040518083038186803b1580156110a357600080fd5b505afa1580156110b7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110db9190611fd2565b90505b808410156110ec57836110ee565b805b93506110fb8686866114d6565b9695505050505050565b61110d6112a0565b60025460405163f7ea7a3d60e01b8152600481018390526001600160a01b039091169063f7ea7a3d90602401600060405180830381600087803b15801561115357600080fd5b505af1158015611167573d6000803e3d6000fd5b5050505050565b6000806111796119f3565b6007546040516319d5c66560e01b81526001600160a01b03868116600483015260248201929092529116906319d5c6659060440160606040518083038186803b1580156111c557600080fd5b505afa1580156111d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111fd9190612068565b50506002546040516370a0823160e01b81526001600160a01b038681166004830152929350600092909116906370a082319060240160206040518083038186803b15801561124a57600080fd5b505afa15801561125e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112829190611fd2565b905080821115611296575060009392505050565b61078c8183611a0a565b6000546001600160a01b031633146113125760405162461bcd60e51b815260206004820152602f60248201527f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726660448201526e37b936903a3434b99030b1ba34b7b760891b6064820152608401610b3f565b565b61131c6119f3565b6007546040516301670a7b60e21b81526001600160a01b038581166004830152602482019290925291169063059c29ec9060440160206040518083038186803b15801561136857600080fd5b505afa15801561137c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a09190611fd2565b156113fb5760405162461bcd60e51b815260206004820152602560248201527f43616e6e6f74207472616e7366657220647572696e672077616974696e672070604482015264195c9a5bd960da1b6064820152608401610b3f565b806114058361116e565b101561146b5760405162461bcd60e51b815260206004820152602f60248201527f496e73756666696369656e742062616c616e636520616674657220616e79207360448201526e6574746c656d656e74206f77696e6760881b6064820152608401610b3f565b611473611a68565b6001600160a01b03166342a28e216007546040518263ffffffff1660e01b81526004016114a291815260200190565b60006040518083038186803b1580156114ba57600080fd5b505afa1580156114ce573d6000803e3d6000fd5b505050505050565b600254604051636eb1769f60e11b81526001600160a01b0385811660048301523360248301526000926000199291169063dd62ed3e9060440160206040518083038186803b15801561152757600080fd5b505afa15801561153b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155f9190611fd2565b1461166857600254604051636eb1769f60e11b81526001600160a01b038681166004830152336024830181905292169163da46098c91879190611600908790869063dd62ed3e906044015b60206040518083038186803b1580156115c257600080fd5b505afa1580156115d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115fa9190611fd2565b90611a0a565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401600060405180830381600087803b15801561164f57600080fd5b505af1158015611663573d6000803e3d6000fd5b505050505b61078c848484611a82565b600061069082611c88565b6002546040516370a0823160e01b81526001600160a01b0384811660048301529091169063b46310f690849061171290859085906370a08231906024015b60206040518083038186803b1580156116d457600080fd5b505afa1580156116e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061170c9190611fd2565b90611cf1565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561175857600080fd5b505af115801561176c573d6000803e3d6000fd5b5050600254604080516318160ddd60e01b815290516001600160a01b03909216935063f7ea7a3d92506117c391859185916318160ddd91600480820192602092909190829003018186803b1580156116d457600080fd5b6040518263ffffffff1660e01b81526004016117e191815260200190565b600060405180830381600087803b1580156117fb57600080fd5b505af115801561180f573d6000803e3d6000fd5b50506040518381526001600160a01b0385169250600091507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6002546040516370a0823160e01b81526001600160a01b038481166004830152600092169063b46310f690859061189b90869085906370a08231906024016115aa565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b1580156118e157600080fd5b505af11580156118f5573d6000803e3d6000fd5b5050600254604080516318160ddd60e01b815290516001600160a01b03909216935063f7ea7a3d925061194c91869185916318160ddd91600480820192602092909190829003018186803b1580156115c257600080fd5b6040518263ffffffff1660e01b815260040161196a91815260200190565b600060405180830381600087803b15801561198457600080fd5b505af1158015611998573d6000803e3d6000fd5b5050604051848152600092506001600160a01b03861691507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a350600192915050565b600061078c848484611a82565b60006107706822bc31b430b733b2b960b91b611d50565b600082821115611a5c5760405162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f7700006044820152606401610b3f565b600061078c8385612096565b60006107706b53797374656d53746174757360a01b611d50565b60006001600160a01b03831615801590611aa557506001600160a01b0383163014155b611af15760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74207472616e7366657220746f20746869732061646472657373006044820152606401610b3f565b6002546040516370a0823160e01b81526001600160a01b0386811660048301529091169063b46310f6908690611b3390869085906370a08231906024016115aa565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611b7957600080fd5b505af1158015611b8d573d6000803e3d6000fd5b50506002546040516370a0823160e01b81526001600160a01b038781166004830152909116925063b46310f691508590611bd390869085906370a08231906024016116bc565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015611c1957600080fd5b505af1158015611c2d573d6000803e3d6000fd5b50505050826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c7691815260200190565b60405180910390a35060019392505050565b6000611c926119f3565b6001600160a01b0316826001600160a01b03161480611cc95750611cb4611dcc565b6001600160a01b0316826001600160a01b0316145b806106905750611cd7611de0565b6001600160a01b0316826001600160a01b03161492915050565b600080611cfe83856120ad565b905083811015610df45760405162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f7700000000006044820152606401610b3f565b600081815260066020908152604080832054905170026b4b9b9b4b7339030b2323932b9b99d1607d1b92810192909252603182018490526001600160a01b0316908115159060510160405160208183030381529060405290611dc55760405162461bcd60e51b8152600401610b3f9190611e4c565b5092915050565b60006107706524b9b9bab2b960d11b611d50565b60006107707027b33321b430b4b722bc31b430b733b2b960791b611d50565b6000815180845260005b81811015611e2557602081850181015186830182015201611e09565b81811115611e37576000602083870101525b50601f01601f19169290920160200192915050565b602081526000610df46020830184611dff565b6001600160a01b0381168114611e7457600080fd5b50565b60008060408385031215611e8a57600080fd5b8235611e9581611e5f565b946020939093013593505050565b600060208284031215611eb557600080fd5b8135610df481611e5f565b600080600060608486031215611ed557600080fd5b8335611ee081611e5f565b92506020840135611ef081611e5f565b929592945050506040919091013590565b6020808252825182820181905260009190848201906040850190845b81811015611f3957835183529284019291840191600101611f1d565b50909695505050505050565b60008060408385031215611f5857600080fd5b8235611f6381611e5f565b91506020830135611f7381611e5f565b809150509250929050565b600060208284031215611f9057600080fd5b5035919050565b600181811c90821680611fab57607f821691505b60208210811415611fcc57634e487b7160e01b600052602260045260246000fd5b50919050565b600060208284031215611fe457600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561201357600080fd5b8151610df481611e5f565b634e487b7160e01b600052601160045260246000fd5b60006000198214156120485761204861201e565b5060010190565b82815260406020820152600061078c6040830184611dff565b60008060006060848603121561207d57600080fd5b8351925060208401519150604084015190509250925092565b6000828210156120a8576120a861201e565b500390565b600082198211156120c0576120c061201e565b50019056fea2646970667358221220ab3d86a5fbec1420bed537e5d509897a1f23255073638c2c18175b724f76bd9b64736f6c63430008090033

[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.