false
false
0

Contract Address Details

0x1000000000000000000000000000000000000006

Contract Name
InitialAirdrop
Creator
Balance
0 FLR
Tokens
Fetching tokens...
Transactions
4,084 Transactions
Transfers
3 Transfers
Gas Used
6,731,050,985
Last Balance Update
26800393
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
InitialAirdrop




Optimization enabled
true
Compiler version
v0.7.6+commit.7338295f




Optimization runs
200
Verified at
2022-07-13T21:03:57.105333Z

./contracts/genesis/implementation/InitialAirdrop.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;

import "../../governance/implementation/GovernedAtGenesis.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
import "@openzeppelin/contracts/math/Math.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "../../utils/implementation/SafePct.sol";

/**
 * @title InitialAirdrop
 * @notice A contract to manage the initial airdrop allocation. 
 * @notice The balance that will be added to this contract must initially be a part of circulating supply 
 **/
contract InitialAirdrop is GovernedAtGenesis, ReentrancyGuard {
    using SafeMath for uint256;
    using SafePct for uint256;

    // constants
    uint256 internal constant CLAIMED_AT_GENESIS_BIPS = 1500;
    uint256 internal constant TOTAL_BIPS = 10000;

    // storage
    address[] public airdropAccounts;
    mapping(address => uint256) public airdropAmountsWei;
    uint256 public totalInitialAirdropWei;          // Total wei to be distributed by this contract (initial airdrop)
    uint256 public initialAirdropStartTs;           // Day 0 when airdrop starts
    uint256 public latestAirdropStartTs;            // Latest day 0 when airdrop starts
    uint256 public totalTransferredAirdropWei;      // All wei already transferred
    uint256 public nextAirdropAccountIndexToTransfer;

    // Errors
    string internal constant ERR_OUT_OF_BALANCE = "balance too low";
    string internal constant ERR_TOO_MANY = "too many";
    string internal constant ERR_NOT_STARTED = "not started";
    string internal constant ERR_ARRAY_MISMATCH = "arrays lengths mismatch";
    string internal constant ERR_ALREADY_SET = "already set";
    string internal constant ERR_WRONG_START_TIMESTAMP = "wrong start timestamp";
    string internal constant ERR_ALREADY_STARTED = "already started";

    // Events
    event AccountsAdded(address[] accounts);
    event AirdropStart(uint256 initialAirdropStartTs);
    event AirdropTransferFailure(address indexed account, uint256 amountWei);

    /**
     * @dev This modifier ensures that this contract's balance matches the expected balance.
     */
    modifier mustBalance {
        _;
        require (_getExpectedBalance() <= address(this).balance, ERR_OUT_OF_BALANCE);
    }

    /**
     * @dev This modifier ensures that the airdrop was already started
     */
    modifier airdropStarted {
        require (initialAirdropStartTs != 0 && initialAirdropStartTs < block.timestamp, ERR_NOT_STARTED);
        _;
    }

    /**
     * @dev This constructor should contain no code as this contract is pre-loaded into the genesis block.
     *   The super constructor is called for testing convenience.
     */
    constructor() GovernedAtGenesis(address(0)) {
        /* empty block */
    }

    /**
     * @notice Method to set addresses and their respective balances in batches to this contract (initial airdrop)
     * @param _accounts         Array of adresses we are adding in batch
     * @param _balances         Array of balances to be airdropped to respective accounts (total amount - 100%)
     * @dev Note that _toAddresses and _balances arrays must be of equal length
     * @dev Note that script must use the same batches to fill data (if restarted), otherwise duplicates may occure
     */
    function setAirdropBalances(address[] calldata _accounts, uint256[] calldata _balances) external onlyGovernance {
        require(_accounts.length <= 1000, ERR_TOO_MANY);
        require(_accounts.length == _balances.length, ERR_ARRAY_MISMATCH);
        require (initialAirdropStartTs == 0, ERR_ALREADY_STARTED);

        if (airdropAmountsWei[_accounts[0]] > 0) return; // batch already added
        for (uint16 i = 0; i < _accounts.length; i++) {
            address airdropAccount = _accounts[i];
            uint256 airdropAmountWei = _balances[i].mulDiv(CLAIMED_AT_GENESIS_BIPS, TOTAL_BIPS);
            airdropAccounts.push(airdropAccount);
            airdropAmountsWei[airdropAccount] = airdropAmountWei;
            totalInitialAirdropWei = totalInitialAirdropWei.add(airdropAmountWei);
        }
        // We added the accounts to airdrop, emit event
        emit AccountsAdded(_accounts);
    }

    /** 
     * @notice Latest start of the initial airdrop at _latestAirdropStartTs timestamp
     * @param _latestAirdropStartTs point in time when latest start is possible
     */
    function setLatestAirdropStart(uint256 _latestAirdropStartTs) external onlyGovernance {
        require(latestAirdropStartTs == 0, ERR_ALREADY_SET);
        latestAirdropStartTs = _latestAirdropStartTs;
    }

    /** 
     * @notice Start the initial airdrop at _initialAirdropStartTs timestamp
     * @param _initialAirdropStartTs point in time when we start
     * @dev should be called immediately after all airdrop accounts and balances are set
     */
    function setAirdropStart(uint256 _initialAirdropStartTs) external onlyGovernance mustBalance {
        require(initialAirdropStartTs == 0 || initialAirdropStartTs > block.timestamp, ERR_ALREADY_STARTED);
        require(initialAirdropStartTs < _initialAirdropStartTs && _initialAirdropStartTs <= latestAirdropStartTs,
            ERR_WRONG_START_TIMESTAMP);
        initialAirdropStartTs = _initialAirdropStartTs;
        emit AirdropStart(_initialAirdropStartTs);
    }

    /**
     * @notice Method for transfering initial airdrop amounts in batches of 50
     */
    function transferAirdrop() external airdropStarted mustBalance nonReentrant {
        uint256 upperBound = Math.min(nextAirdropAccountIndexToTransfer + 50, airdropAccounts.length);
        for (uint256 i = nextAirdropAccountIndexToTransfer; i < upperBound; i++) {
            // Get the account and amount
            address account = airdropAccounts[i];
            uint256 amountWei = airdropAmountsWei[account];
            // update state
            delete airdropAmountsWei[account];
            delete airdropAccounts[i];
            // Update grand total transferred
            totalTransferredAirdropWei = totalTransferredAirdropWei.add(amountWei);
            // Send
            /* solhint-disable avoid-low-level-calls */
            //slither-disable-next-line arbitrary-send
            (bool success, ) = account.call{ value: amountWei, gas: 21000 }("");
            /* solhint-enable avoid-low-level-calls */
            if (!success) {
                emit AirdropTransferFailure(account, amountWei);
            }
        }

        // Update current position
        nextAirdropAccountIndexToTransfer = upperBound;
    }

    /**
     * @notice Return the number of airdrop accounts
     */
    function airdropAccountsLength() external view returns (uint256) {
        return airdropAccounts.length;
    }

    /**
     * @notice Compute the expected balance of this contract.
     * @param _balanceExpectedWei   The computed balance expected.
     */
    function _getExpectedBalance() private view returns(uint256 _balanceExpectedWei) {
        return totalInitialAirdropWei.sub(totalTransferredAirdropWei);
    }

}
        

@openzeppelin/contracts/math/Math.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a >= b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow, so we distribute
        return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
    }
}
          

./contracts/governance/implementation/GovernedAtGenesis.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;

import "./GovernedBase.sol";


/**
 * @title Governed At Genesis
 * @dev This contract enforces a fixed governance address when the constructor
 *  is not executed on a contract (for instance when directly loaded to the genesis block).
 *  This is required to fix governance on a contract when the network starts, at such point
 *  where theoretically no accounts yet exist, and leaving it ungoverned could result in a race
 *  to claim governance by an unauthorized address.
 **/
contract GovernedAtGenesis is GovernedBase {
    constructor(address _governance) GovernedBase(_governance) { }

    /**
     * @notice Set governance to a fixed address when constructor is not called.
     **/
    function initialiseFixedAddress() public virtual returns (address) {
        address governanceAddress = address(0xfffEc6C83c8BF5c3F4AE0cCF8c45CE20E4560BD7);
        
        super.initialise(governanceAddress);
        return governanceAddress;
    }

    /**
     * @notice Disallow initialise to be called
     * @param _governance The governance address for initial claiming
     **/
    // solhint-disable-next-line no-unused-vars
    function initialise(address _governance) public override pure {
        assert(false);
    }
}
          

./contracts/governance/implementation/GovernedBase.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;

import "../../userInterfaces/IGovernanceSettings.sol";


/**
 * @title Governed Base
 * @notice This abstract base class defines behaviors for a governed contract.
 * @dev This class is abstract so that specific behaviors can be defined for the constructor.
 *   Contracts should not be left ungoverned, but not all contract will have a constructor
 *   (for example those pre-defined in genesis).
 **/
abstract contract GovernedBase {
    struct TimelockedCall {
        uint256 allowedAfterTimestamp;
        bytes encodedCall;
    }
    
    // solhint-disable-next-line const-name-snakecase
    IGovernanceSettings public constant governanceSettings = 
        IGovernanceSettings(0x1000000000000000000000000000000000000007);

    address private initialGovernance;

    bool private initialised;
    
    bool public productionMode;
    
    bool private executing;
    
    mapping(bytes4 => TimelockedCall) public timelockedCalls;
    
    event GovernanceCallTimelocked(bytes4 selector, uint256 allowedAfterTimestamp, bytes encodedCall);
    event TimelockedGovernanceCallExecuted(bytes4 selector, uint256 timestamp);
    event TimelockedGovernanceCallCanceled(bytes4 selector, uint256 timestamp);
    
    event GovernanceInitialised(address initialGovernance);
    event GovernedProductionModeEntered(address governanceSettings);
    
    modifier onlyGovernance {
        if (executing || !productionMode) {
            _beforeExecute();
            _;
        } else {
            _recordTimelockedCall(msg.data);
        }
    }
    
    modifier onlyImmediateGovernance () {
        _checkOnlyGovernance();
        _;
    }

    constructor(address _initialGovernance) {
        if (_initialGovernance != address(0)) {
            initialise(_initialGovernance);
        }
    }

    /**
     * @notice Execute the timelocked governance calls once the timelock period expires.
     * @dev Only executor can call this method.
     * @param _selector The method selector (only one timelocked call per method is stored).
     */
    function executeGovernanceCall(bytes4 _selector) external {
        require(governanceSettings.isExecutor(msg.sender), "only executor");
        TimelockedCall storage call = timelockedCalls[_selector];
        require(call.allowedAfterTimestamp != 0, "timelock: invalid selector");
        require(block.timestamp >= call.allowedAfterTimestamp, "timelock: not allowed yet");
        bytes memory encodedCall = call.encodedCall;
        delete timelockedCalls[_selector];
        executing = true;
        //solhint-disable-next-line avoid-low-level-calls
        (bool success,) = address(this).call(encodedCall);
        executing = false;
        emit TimelockedGovernanceCallExecuted(_selector, block.timestamp);
        _passReturnOrRevert(success);
    }
    
    /**
     * Cancel a timelocked governance call before it has been executed.
     * @dev Only governance can call this method.
     * @param _selector The method selector.
     */
    function cancelGovernanceCall(bytes4 _selector) external onlyImmediateGovernance {
        require(timelockedCalls[_selector].allowedAfterTimestamp != 0, "timelock: invalid selector");
        emit TimelockedGovernanceCallCanceled(_selector, block.timestamp);
        delete timelockedCalls[_selector];
    }
    
    /**
     * Enter the production mode after all the initial governance settings have been set.
     * This enables timelocks and the governance is afterwards obtained by calling 
     * governanceSettings.getGovernanceAddress(). 
     */
    function switchToProductionMode() external {
        _checkOnlyGovernance();
        require(!productionMode, "already in production mode");
        initialGovernance = address(0);
        productionMode = true;
        emit GovernedProductionModeEntered(address(governanceSettings));
    }

    /**
     * @notice Initialize the governance address if not first initialized.
     */
    function initialise(address _initialGovernance) public virtual {
        require(initialised == false, "initialised != false");
        initialised = true;
        initialGovernance = _initialGovernance;
        emit GovernanceInitialised(_initialGovernance);
    }
    
    /**
     * Returns the current effective governance address.
     */
    function governance() public view returns (address) {
        return productionMode ? governanceSettings.getGovernanceAddress() : initialGovernance;
    }

    function _beforeExecute() private {
        if (executing) {
            // can only be run from executeGovernanceCall(), where we check that only executor can call
            // make sure nothing else gets executed, even in case of reentrancy
            assert(msg.sender == address(this));
            executing = false;
        } else {
            // must be called with: productionMode=false
            // must check governance in this case
            _checkOnlyGovernance();
        }
    }

    function _recordTimelockedCall(bytes calldata _data) private {
        _checkOnlyGovernance();
        bytes4 selector;
        //solhint-disable-next-line no-inline-assembly
        assembly {
            selector := calldataload(_data.offset)
        }
        uint256 timelock = governanceSettings.getTimelock();
        uint256 allowedAt = block.timestamp + timelock;
        timelockedCalls[selector] = TimelockedCall({
            allowedAfterTimestamp: allowedAt,
            encodedCall: _data
        });
        emit GovernanceCallTimelocked(selector, allowedAt, _data);
    }
    
    function _checkOnlyGovernance() private view {
        require(msg.sender == governance(), "only governance");
    }
    
    function _passReturnOrRevert(bool _success) private pure {
        // pass exact return or revert data - needs to be done in assembly
        //solhint-disable-next-line no-inline-assembly
        assembly {
            let size := returndatasize()
            let ptr := mload(0x40)
            mstore(0x40, add(ptr, size))
            returndatacopy(ptr, 0, size)
            if _success {
                return(ptr, size)
            }
            revert(ptr, size)
        }
    }
}
          

./contracts/userInterfaces/IGovernanceSettings.sol

// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;


/**
 * A special contract that holds Flare governance address.
 * This contract enables updating governance address and timelock only by hard forking the network,
 * meaning only by updating validator code.
 */
interface IGovernanceSettings {
    /**
     * Get the governance account address.
     * The governance address can only be changed by a hardfork.
     */
    function getGovernanceAddress() external view returns (address);
    
    /**
     * Get the time in seconds that must pass between a governance call and execution.
     * The timelock value can only be changed by a hardfork.
     */
    function getTimelock() external view returns (uint256);
    
    /**
     * Get the addresses of the accounts that are allowed to execute the timelocked governance calls
     * once the timelock period expires.
     * Executors can be changed without a hardfork, via a normal governance call.
     */
    function getExecutors() external view returns (address[] memory);
    
    /**
     * Check whether an address is one of the executors.
     */
    function isExecutor(address _address) external view returns (bool);
}
          

./contracts/utils/implementation/SafePct.sol

// SPDX-License-Identifier: MIT

pragma solidity 0.7.6;
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";

/**
 * @dev Compute percentages safely without phantom overflows.
 *
 * Intermediate operations can overflow even when the result will always
 * fit into computed type. Developers usually
 * assume that overflows raise errors. `SafePct` restores this intuition by
 * reverting the transaction when such 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.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafePct {
    using SafeMath for uint256;
    /**
     * Requirements:
     *
     * - intermediate operations must revert on overflow
     */
    function mulDiv(uint256 x, uint256 y, uint256 z) internal pure returns (uint256) {
        require(z > 0, "Division by zero");

        if (x == 0) return 0;
        uint256 xy = x * y;
        if (xy / x == y) { // no overflow happened - same as in SafeMath mul
            return xy / z;
        }

        //slither-disable-next-line divide-before-multiply
        uint256 a = x / z;
        uint256 b = x % z; // x = a * z + b

        //slither-disable-next-line divide-before-multiply
        uint256 c = y / z;
        uint256 d = y % z; // y = c * z + d

        return (a.mul(c).mul(z)).add(a.mul(d)).add(b.mul(c)).add(b.mul(d).div(z));
    }
}
          

@openzeppelin/contracts/math/SafeMath.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, 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-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @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");
        return a - b;
    }

    /**
     * @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) {
        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, reverting 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) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting 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;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * 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, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * 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, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}
          

@openzeppelin/contracts/utils/ReentrancyGuard.sol

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor () internal {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}
          

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"AccountsAdded","inputs":[{"type":"address[]","name":"accounts","internalType":"address[]","indexed":false}],"anonymous":false},{"type":"event","name":"AirdropStart","inputs":[{"type":"uint256","name":"initialAirdropStartTs","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"AirdropTransferFailure","inputs":[{"type":"address","name":"account","internalType":"address","indexed":true},{"type":"uint256","name":"amountWei","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceCallTimelocked","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"allowedAfterTimestamp","internalType":"uint256","indexed":false},{"type":"bytes","name":"encodedCall","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceInitialised","inputs":[{"type":"address","name":"initialGovernance","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"GovernedProductionModeEntered","inputs":[{"type":"address","name":"governanceSettings","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"TimelockedGovernanceCallCanceled","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TimelockedGovernanceCallExecuted","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"airdropAccounts","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"airdropAccountsLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"airdropAmountsWei","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancelGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"executeGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"governance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IGovernanceSettings"}],"name":"governanceSettings","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"initialAirdropStartTs","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[],"name":"initialise","inputs":[{"type":"address","name":"_governance","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"initialiseFixedAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"latestAirdropStartTs","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nextAirdropAccountIndexToTransfer","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"productionMode","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAirdropBalances","inputs":[{"type":"address[]","name":"_accounts","internalType":"address[]"},{"type":"uint256[]","name":"_balances","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAirdropStart","inputs":[{"type":"uint256","name":"_initialAirdropStartTs","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setLatestAirdropStart","inputs":[{"type":"uint256","name":"_latestAirdropStartTs","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"switchToProductionMode","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"allowedAfterTimestamp","internalType":"uint256"},{"type":"bytes","name":"encodedCall","internalType":"bytes"}],"name":"timelockedCalls","inputs":[{"type":"bytes4","name":"","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalInitialAirdropWei","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalTransferredAirdropWei","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferAirdrop","inputs":[]}]
              

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101375760003560e01c806374e6310e116100b8578063c9f960eb1161007c578063c9f960eb146103d7578063ce592dfb146103df578063d5261971146103e7578063e17f212e146103ef578063ea1e63211461040b578063f5a983831461043157610137565b806374e6310e146102de5780638dc7b1a91461038457806390568f81146103a15780639d6a890f146103a9578063c602a77e146103cf57610137565b80635ff27079116100ff5780635ff27079146101a757806361235585146101d057806362354e031461029257806367fc40291461029a5780636de80541146102c157610137565b80633f630c3a1461013c57806346a549b5146101565780634a4b698a1461015e5780635aa6e675146101975780635dcb01701461019f575b600080fd5b610144610439565b60408051918252519081900360200190f35b61014461043f565b61017b6004803603602081101561017457600080fd5b5035610445565b604080516001600160a01b039092168252519081900360200190f35b61017b61046f565b610144610504565b6101ce600480360360208110156101bd57600080fd5b50356001600160e01b03191661050a565b005b6101ce600480360360408110156101e657600080fd5b81019060208101813564010000000081111561020157600080fd5b82018360208201111561021357600080fd5b8035906020019184602083028401116401000000008311171561023557600080fd5b91939092909160208101903564010000000081111561025357600080fd5b82018360208201111561026557600080fd5b8035906020019184602083028401116401000000008311171561028757600080fd5b50909250905061085f565b61017b610bd5565b6101ce600480360360208110156102b057600080fd5b50356001600160e01b031916610be0565b6101ce600480360360208110156102d757600080fd5b5035610cc8565b610305600480360360208110156102f457600080fd5b50356001600160e01b031916610ed5565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610348578181015183820152602001610330565b50505050905090810190601f1680156103755780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b6101ce6004803603602081101561039a57600080fd5b5035610f7b565b610144611027565b6101ce600480360360208110156103bf57600080fd5b50356001600160a01b031661102d565b61014461102f565b61017b611035565b610144611055565b6101ce61105b565b6103f7611303565b604080519115158252519081900360200190f35b6101446004803603602081101561042157600080fd5b50356001600160a01b0316611313565b6101ce611325565b60055481565b60075481565b6003818154811061045557600080fd5b6000918252602090912001546001600160a01b0316905081565b60008054600160a81b900460ff16610492576000546001600160a01b03166104ff565b60076001609c1b016001600160a01b031663732524946040518163ffffffff1660e01b815260040160206040518083038186803b1580156104d257600080fd5b505afa1580156104e6573d6000803e3d6000fd5b505050506040513d60208110156104fc57600080fd5b50515b905090565b60065481565b60408051630debfda360e41b8152336004820152905160076001609c1b019163debfda30916024808301926020929190829003018186803b15801561054e57600080fd5b505afa158015610562573d6000803e3d6000fd5b505050506040513d602081101561057857600080fd5b50516105bb576040805162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b604482015290519081900360640190fd5b6001600160e01b0319811660009081526001602052604090208054610627576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b805442101561067d576040805162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f7765642079657400000000000000604482015290519081900360640190fd5b6000816001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156107175780601f106106ec57610100808354040283529160200191610717565b820191906000526020600020905b8154815290600101906020018083116106fa57829003601f168201915b5050506001600160e01b031986166000908152600160208190526040822082815594955090925061074b915083018261198b565b50506000805460ff60b01b1916600160b01b178155604051825130918491819060208401908083835b602083106107935780518252601f199092019160209182019101610774565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d80600081146107f5576040519150601f19603f3d011682016040523d82523d6000602084013e6107fa565b606091505b50506000805460ff60b01b19169055604080516001600160e01b03198716815242602082015281519293507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438929081900390910190a1610859816113df565b50505050565b600054600160b01b900460ff16806108815750600054600160a81b900460ff16155b15610bca5761088e6113fc565b604080518082019091526008815267746f6f206d616e7960c01b60208201526103e884111561093b5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156109005781810151838201526020016108e8565b50505050905090810190601f16801561092d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060408051808201909152601781527f617272617973206c656e67746873206d69736d6174636800000000000000000060208201528382146109be5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109005781810151838201526020016108e8565b5060065460408051808201909152600f81526e185b1c9958591e481cdd185c9d1959608a1b60208201529015610a355760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109005781810151838201526020016108e8565b5060006004600086866000818110610a4957fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b03168152602001908152602001600020541115610a8557610bc5565b60005b61ffff8116841115610b6057600085858361ffff16818110610aa657fe5b905060200201356001600160a01b031690506000610ae96105dc61271087878761ffff16818110610ad357fe5b905060200201356114339092919063ffffffff16565b60038054600181019091557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b0385169081179091556000908152600460205260409020819055600554909150610b539082611541565b6005555050600101610a88565b507fc21490756c6f0185a8ad2363084fd0a45b06707979f77786b5e681bddc1d2fa1848460405180806020018281038252848482818152602001925060200280828437600083820152604051601f909101601f19169092018290039550909350505050a15b610859565b6108596000366115a4565b60076001609c1b0181565b610be8611727565b6001600160e01b03198116600090815260016020526040902054610c53576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b604080516001600160e01b03198316815242602082015281517f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8929181900390910190a16001600160e01b03198116600090815260016020819052604082208281559190610cc39083018261198b565b505050565b600054600160b01b900460ff1680610cea5750600054600160a81b900460ff16155b15610ec757610cf76113fc565b6006541580610d07575042600654115b6040518060400160405280600f81526020016e185b1c9958591e481cdd185c9d1959608a1b81525090610d7b5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109005781810151838201526020016108e8565b5080600654108015610d8f57506007548111155b60405180604001604052806015815260200174077726f6e672073746172742074696d657374616d7605c1b81525090610e095760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109005781810151838201526020016108e8565b5060068190556040805182815290517fd17095b0cb6319c5430ce8553f9ce78001789e1f94f47f377653a16198f2a90b9181900360200190a147610e4b611786565b11156040518060400160405280600f81526020016e62616c616e636520746f6f206c6f7760881b81525090610ec15760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109005781810151838201526020016108e8565b50610ed2565b610ed26000366115a4565b50565b600160208181526000928352604092839020805481840180548651600296821615610100026000190190911695909504601f81018590048502860185019096528585529094919392909190830182828015610f715780601f10610f4657610100808354040283529160200191610f71565b820191906000526020600020905b815481529060010190602001808311610f5457829003601f168201915b5050505050905082565b600054600160b01b900460ff1680610f9d5750600054600160a81b900460ff16155b15610ec757610faa6113fc565b60075460408051808201909152600b81526a185b1c9958591e481cd95d60aa1b6020820152901561101c5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109005781810151838201526020016108e8565b506007819055610ed2565b60085481565bfe5b60095481565b600073fffec6c83c8bf5c3f4ae0ccf8c45ce20e4560bd76104ff8161179f565b60035490565b6006541580159061106d575042600654105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906110dd5760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109005781810151838201526020016108e8565b50600280541415611135576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002805560095460035460009161115191603290910190611858565b6009549091505b8181101561127b5760006003828154811061116f57fe5b60009182526020808320909101546001600160a01b031680835260049091526040822080549290556003805491935090849081106111a957fe5b600091825260209091200180546001600160a01b03191690556008546111cf9082611541565b6008556040516000906001600160a01b0384169061520890849084818181858888f193505050503d8060008114611222576040519150601f19603f3d011682016040523d82523d6000602084013e611227565b606091505b5050905080611270576040805183815290516001600160a01b038516917fa63e265bae965e6aae4283d17bf7ba298580ba5924f711fe7da1a7ee4ae19ef5919081900360200190a25b505050600101611158565b5060095560016002554761128d611786565b11156040518060400160405280600f81526020016e62616c616e636520746f6f206c6f7760881b81525090610ed25760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156109005781810151838201526020016108e8565b600054600160a81b900460ff1681565b60046020526000908152604090205481565b61132d611727565b600054600160a81b900460ff161561138c576040805162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f6465000000000000604482015290519081900360640190fd5b60008054600161ff0160a01b031916600160a81b1790556040805160076001609c1b01815290517f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9181900360200190a1565b3d604051818101604052816000823e82156113f8578181f35b8181fd5b600054600160b01b900460ff16156114295733301461141757fe5b6000805460ff60b01b19169055611431565b611431611727565b565b600080821161147c576040805162461bcd60e51b815260206004820152601060248201526f4469766973696f6e206279207a65726f60801b604482015290519081900360640190fd5b836114895750600061153a565b8383028385828161149657fe5b0414156114af578281816114a657fe5b0491505061153a565b60008386816114ba57fe5b04905060008487816114c857fe5b06905060008587816114d657fe5b04905060008688816114e457fe5b0690506115326114fe886114f8868561186e565b906118c7565b61152c61150b868661186e565b61152c611518898761186e565b61152c8d6115268c8b61186e565b9061186e565b90611541565b955050505050505b9392505050565b60008282018381101561159b576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b90505b92915050565b6115ac611727565b600082359050600060076001609c1b016001600160a01b0316636221a54b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156115f457600080fd5b505afa158015611608573d6000803e3d6000fd5b505050506040513d602081101561161e57600080fd5b505160408051808201825242830180825282516020601f89018190048102820181019094528781529394509290918281019190889088908190840183828082843760009201829052509390945250506001600160e01b031986168152600160208181526040909220845181558483015180519194506116a2939285019201906119cf565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405180856001600160e01b0319168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f191690920182900397509095505050505050a15050505050565b61172f61046f565b6001600160a01b0316336001600160a01b031614611431576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b60006104ff60085460055461192e90919063ffffffff16565b600054600160a01b900460ff16156117f5576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b6000818310611867578161159b565b5090919050565b60008261187d5750600061159e565b8282028284828161188a57fe5b041461159b5760405162461bcd60e51b8152600401808060200182810382526021815260200180611a716021913960400191505060405180910390fd5b600080821161191d576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161192657fe5b049392505050565b600082821115611985576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b50805460018160011615610100020316600290046000825580601f106119b15750610ed2565b601f016020900490600052602060002090810190610ed29190611a5b565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611a055760008555611a4b565b82601f10611a1e57805160ff1916838001178555611a4b565b82800160010185558215611a4b579182015b82811115611a4b578251825591602001919060010190611a30565b50611a57929150611a5b565b5090565b5b80821115611a575760008155600101611a5c56fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220de084bcc806438ade1d29f53684bb8a7c861697d43c2ed767e4eee2004867fda64736f6c63430007060033