-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathverify-input.json
More file actions
72 lines (72 loc) · 66.2 KB
/
verify-input.json
File metadata and controls
72 lines (72 loc) · 66.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{
"language": "Solidity",
"sources": {
"contracts/@openzeppelin/contracts/ERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./IERC20Metadata.sol\";\nimport \"./utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * The defaut value of {decimals} is 18. To select a different value for\n * {decimals} you should overload it.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\n * overloaded;\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view virtual override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n\n uint256 currentAllowance = _allowances[sender][_msgSender()];\n require(currentAllowance >= amount, \"ERC20: transfer amount exceeds allowance\");\n _approve(sender, _msgSender(), currentAllowance - amount);\n\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n uint256 currentAllowance = _allowances[_msgSender()][spender];\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\n\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n uint256 senderBalance = _balances[sender];\n require(senderBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n _balances[sender] = senderBalance - amount;\n _balances[recipient] += amount;\n\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n _balances[account] += amount;\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n _balances[account] = accountBalance - amount;\n _totalSupply -= amount;\n\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n"
},
"contracts/@openzeppelin/contracts/IERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n"
},
"contracts/@openzeppelin/contracts/IERC20Metadata.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n"
},
"contracts/@openzeppelin/contracts/Ownable.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(\n address indexed previousOwner,\n address indexed newOwner\n );\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() external virtual onlyOwner {\n _renounceOwnership();\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) external virtual onlyOwner {\n require(\n newOwner != address(0),\n \"Ownable: new owner is the zero address\"\n );\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n function _renounceOwnership() private {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n}\n"
},
"contracts/@openzeppelin/contracts/OwnableUpgradeableWithExpiry.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./utils/ContextUpgradeable.sol\";\nimport \"./utils/Initializable.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeableWithExpiry is Initializable, ContextUpgradeable {\n address private _owner;\n uint256 private _deployTimestamp;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal initializer {\n address msgSender = _msgSender();\n _owner = msgSender;\n _deployTimestamp = block.timestamp;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view virtual returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() external virtual onlyOwner {\n _renounceOwnership();\n }\n\n /**\n * @dev Get the timestamp of ownership expiry.\n * @return The timestamp of ownership expiry.\n */\n function getOwnershipExpiryTimestamp() public view returns (uint256) {\n return _deployTimestamp + 82 weeks;\n }\n\n /**\n * @dev Check if the contract ownership is expired.\n * @return True if the contract ownership is expired.\n */\n function isOwnershipExpired() public view returns (bool) {\n return block.timestamp > getOwnershipExpiryTimestamp();\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called after ownership is expired.\n */\n function renounceOwnershipAfterExpiry() external {\n require(isOwnershipExpired(), \"Ownership not yet expired\");\n _renounceOwnership();\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) external virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n\n function _renounceOwnership() private {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n uint256[49] private __gap;\n}"
},
"contracts/@openzeppelin/contracts/SafeERC20.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender) + value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n uint256 newAllowance = oldAllowance - value;\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n"
},
"contracts/@openzeppelin/contracts/security/ReentrancyGuard.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Contract module that helps prevent reentrant calls to a function.\n *\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\n * available, which can be applied to functions to make sure there are no nested\n * (reentrant) calls to them.\n *\n * Note that because there is a single `nonReentrant` guard, functions marked as\n * `nonReentrant` may not call one another. This can be worked around by making\n * those functions `private`, and then adding `external` `nonReentrant` entry\n * points to them.\n *\n * TIP: If you would like to learn more about reentrancy and alternative ways\n * to protect against it, check out our blog post\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\n */\nabstract contract ReentrancyGuard {\n // Booleans are more expensive than uint256 or any type that takes up a full\n // word because each write operation emits an extra SLOAD to first read the\n // slot's contents, replace the bits taken up by the boolean, and then write\n // back. This is the compiler's defense against contract upgrades and\n // pointer aliasing, and it cannot be disabled.\n\n // The values being non-zero value makes deployment a bit more expensive,\n // but in exchange the refund on every call to nonReentrant will be lower in\n // amount. Since refunds are capped to a percentage of the total\n // transaction's gas, it is best to keep them low in cases like this one, to\n // increase the likelihood of the full refund coming into effect.\n uint256 private constant _NOT_ENTERED = 1;\n uint256 private constant _ENTERED = 2;\n\n uint256 private _status;\n\n constructor () {\n _status = _NOT_ENTERED;\n }\n\n /**\n * @dev Prevents a contract from calling itself, directly or indirectly.\n * Calling a `nonReentrant` function from another `nonReentrant`\n * function is not supported. It is possible to prevent this from happening\n * by making the `nonReentrant` function external, and make it call a\n * `private` function that does the actual work.\n */\n modifier nonReentrant() {\n // On the first call to nonReentrant, _notEntered will be true\n require(_status != _ENTERED, \"ReentrancyGuard: reentrant call\");\n\n // Any calls to nonReentrant after this point will fail\n _status = _ENTERED;\n\n _;\n\n // By storing the original value once again, a refund is triggered (see\n // https://eips.ethereum.org/EIPS/eip-2200)\n _status = _NOT_ENTERED;\n }\n}\n"
},
"contracts/@openzeppelin/contracts/utils/Address.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n require(isContract(target), \"Address: delegate call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n"
},
"contracts/@openzeppelin/contracts/utils/Context.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n"
},
"contracts/@openzeppelin/contracts/utils/ContextUpgradeable.sol": {
"content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\nimport \"./Initializable.sol\";\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal initializer {\n __Context_init_unchained();\n }\n\n function __Context_init_unchained() internal initializer {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n uint256[50] private __gap;\n}"
},
"contracts/@openzeppelin/contracts/utils/Initializable.sol": {
"content": "// SPDX-License-Identifier: MIT\n\n// solhint-disable-next-line compiler-version\npragma solidity ^0.8.0;\n\nimport \"./Address.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\n * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}.\n *\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\n */\nabstract contract Initializable {\n\n /**\n * @dev Indicates that the contract has been initialized.\n */\n bool private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Modifier to protect an initializer function from being invoked twice.\n */\n modifier initializer() {\n require(_initializing || !_initialized, \"Initializable: contract is already initialized\");\n\n bool isTopLevelCall = !_initializing;\n if (isTopLevelCall) {\n _initializing = true;\n _initialized = true;\n }\n\n _;\n\n if (isTopLevelCall) {\n _initializing = false;\n }\n }\n}\n"
},
"contracts/@openzeppelin/contracts/utils/Pausable.sol": {
"content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"./ContextUpgradeable.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is ContextUpgradeable {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n require(!paused(), \"Pausable: paused\");\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n require(paused(), \"Pausable: not paused\");\n _;\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n"
},
"contracts/Hyperion.sol": {
"content": "// SPDX-License-Identifier: Apache-2.0\n\npragma solidity ^0.8.0;\n\nimport \"./@openzeppelin/contracts/ERC20.sol\";\nimport \"./@openzeppelin/contracts/Ownable.sol\";\nimport \"./@openzeppelin/contracts/IERC20.sol\";\nimport \"./@openzeppelin/contracts/IERC20Metadata.sol\";\nimport \"./@openzeppelin/contracts/SafeERC20.sol\";\nimport \"./@openzeppelin/contracts/utils/Address.sol\";\nimport \"./@openzeppelin/contracts/utils/Initializable.sol\";\nimport \"./@openzeppelin/contracts/utils/Pausable.sol\";\nimport \"./@openzeppelin/contracts/security/ReentrancyGuard.sol\";\nimport \"./@openzeppelin/contracts/OwnableUpgradeableWithExpiry.sol\";\n\ncontract HeliosERC20 is ERC20, Ownable {\n uint8 private immutable _decimals;\n\n constructor(\n string memory name_,\n string memory symbol_,\n uint8 decimals_\n ) ERC20(name_, symbol_) {\n _decimals = decimals_;\n }\n\n function decimals() public view virtual override returns (uint8) {\n return _decimals;\n }\n\n function mint(address account, uint256 amount) public onlyOwner {\n _mint(account, amount);\n }\n\n function burn(address account, uint256 amount) public onlyOwner {\n _burn(account, amount);\n }\n}\n\ninterface ArbSys {\n function arbBlockNumber() external view returns (uint256);\n}\n\n// This is used purely to avoid stack too deep errors\n// represents everything about a given validator set\nstruct ValsetArgs {\n // the validators in this set, represented by an Ethereum address\n address[] validators;\n // the powers of the given validators in the same order as above\n uint256[] powers;\n // the nonce of this validator set\n uint256 valsetNonce;\n // the reward amount denominated in the below reward token, can be\n // set to zero\n uint256 rewardAmount;\n // the reward token, should be set to the zero address if not being used\n address rewardToken;\n}\n\n// Don't change the order of state for working upgrades.\n// AND BE AWARE OF INHERITANCE VARIABLES!\n// Inherited contracts contain storage slots and must be accounted for in any upgrades\n// always test an exact upgrade on testnet and localhost before mainnet upgrades.\ncontract Hyperion is\n Initializable,\n OwnableUpgradeableWithExpiry,\n Pausable,\n ReentrancyGuard\n{\n using SafeERC20 for IERC20;\n\n // ⚠️ ONLY APPEND TO STATE VARIABLES AND DON'T CHANGE VARIABLE ORDER/DEFINITIONS INCL NOT MAKING THEM IMMUTABLE ⚠️\n\n // These are updated often\n bytes32 public state_lastValsetCheckpoint;\n mapping(address => uint256) public state_lastBatchNonces;\n mapping(bytes32 => uint256) public state_invalidationMapping;\n uint256 public state_lastValsetNonce = 0;\n uint256 public state_lastValsetHeight = 0;\n uint256 public state_lastEventNonce = 0;\n uint256 public state_lastEventHeight = 0;\n\n // These are set once at initialization\n bytes32 public state_hyperionId;\n uint256 public state_powerThreshold;\n\n mapping(address => bool) public isHeliosNativeToken;\n\n uint256 private constant MAX_NONCE_JUMP_LIMIT = 10_000_000_000_000;\n\n // TransactionBatchExecutedEvent and SendToHeliosEvent both include the field _eventNonce.\n // This is incremented every time one of these events is emitted. It is checked by the\n // Helios module to ensure that all events are received in order, and that none are lost.\n //\n // ValsetUpdatedEvent does not include the field _eventNonce because it is never submitted to the Helios\n // module. It is purely for the use of relayers to allow them to successfully submit batches.\n event TransactionBatchExecutedEvent(\n uint256 indexed _batchNonce,\n address indexed _token,\n uint256 _eventNonce\n );\n event SendToHeliosEvent(\n address indexed _tokenContract,\n address indexed _sender,\n bytes32 indexed _destination,\n uint256 _amount,\n uint256 _eventNonce,\n string _data\n );\n event ERC20DeployedEvent(\n string _heliosDenom,\n address indexed _tokenContract,\n string _name,\n string _symbol,\n uint8 _decimals,\n uint256 _eventNonce\n );\n event ValsetUpdatedEvent(\n uint256 indexed _newValsetNonce,\n uint256 _eventNonce,\n uint256 _rewardAmount,\n address _rewardToken,\n address[] _validators,\n uint256[] _powers\n );\n\n function _validateValidatorSet(\n address[] calldata _validators,\n uint256[] calldata _powers,\n uint256 _powerThreshold\n ) private pure {\n // Check that validators and powers set is well-formed\n require(\n _validators.length == _powers.length,\n \"Malformed current validator set\"\n );\n\n // Check cumulative power to ensure the contract has sufficient power to actually\n // pass a vote\n uint256 cumulativePower = 0;\n for (uint256 i = 0; i < _powers.length; i++) {\n cumulativePower = cumulativePower + _powers[i];\n if (cumulativePower > _powerThreshold) {\n break;\n }\n }\n\n require(\n cumulativePower > _powerThreshold,\n \"Submitted validator set signatures do not have enough power.\"\n );\n }\n\n function initialize(\n // A unique identifier for this hyperion instance to use in signatures\n bytes32 _hyperionId,\n // How much voting power is needed to approve operations\n uint256 _powerThreshold,\n // The validator set, not in valset args format since many of it's\n // arguments would never be used in this case\n address[] calldata _validators,\n uint256[] calldata _powers\n ) external initializer {\n __Context_init_unchained();\n __Ownable_init_unchained();\n\n // CHECKS\n\n _validateValidatorSet(_validators, _powers, _powerThreshold);\n\n ValsetArgs memory _valset;\n _valset = ValsetArgs(_validators, _powers, 0, 0, address(0));\n\n bytes32 newCheckpoint = makeCheckpoint(_valset, _hyperionId);\n\n // ACTIONS\n\n state_hyperionId = _hyperionId;\n state_powerThreshold = _powerThreshold;\n state_lastValsetCheckpoint = newCheckpoint;\n state_lastEventNonce = state_lastEventNonce + 1;\n state_lastValsetHeight = getBlockNumber();\n state_lastEventHeight = getBlockNumber();\n // LOGS\n\n emit ValsetUpdatedEvent(\n state_lastValsetNonce,\n state_lastEventNonce,\n 0,\n address(0),\n _validators,\n _powers\n );\n }\n\n function lastBatchNonce(\n address _erc20Address\n ) public view returns (uint256) {\n return state_lastBatchNonces[_erc20Address];\n }\n\n // Utility function to verify geth style signatures\n function verifySig(\n address _signer,\n bytes32 _theHash,\n uint8 _v,\n bytes32 _r,\n bytes32 _s\n ) private pure returns (bool) {\n bytes32 messageDigest = keccak256(\n abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", _theHash)\n );\n return _signer == ecrecover(messageDigest, _v, _r, _s);\n }\n\n // Make a new checkpoint from the supplied validator set\n // A checkpoint is a hash of all relevant information about the valset. This is stored by the contract,\n // instead of storing the information directly. This saves on storage and gas.\n // The format of the checkpoint is:\n // h(hyperionId, \"checkpoint\", valsetNonce, validators[], powers[])\n // Where h is the keccak256 hash function.\n // The validator powers must be decreasing or equal. This is important for checking the signatures on the\n // next valset, since it allows the caller to stop verifying signatures once a quorum of signatures have been verified.\n function makeCheckpoint(\n ValsetArgs memory _valsetArgs,\n bytes32 _hyperionId\n ) private pure returns (bytes32) {\n // bytes32 encoding of the string \"checkpoint\"\n bytes32 methodName = 0x636865636b706f696e7400000000000000000000000000000000000000000000;\n\n bytes32 checkpoint = keccak256(\n abi.encode(\n _hyperionId,\n methodName,\n _valsetArgs.valsetNonce,\n _valsetArgs.validators,\n _valsetArgs.powers,\n _valsetArgs.rewardAmount,\n _valsetArgs.rewardToken\n )\n );\n return checkpoint;\n }\n\n function checkValidatorSignatures(\n // The current validator set and their powers\n address[] memory _currentValidators,\n uint256[] memory _currentPowers,\n // The current validator's signatures\n uint8[] memory _v,\n bytes32[] memory _r,\n bytes32[] memory _s,\n // This is what we are checking they have signed\n bytes32 _theHash,\n uint256 _powerThreshold\n ) private view {\n uint256 cumulativePower = 0;\n\n for (uint256 i = 0; i < _currentValidators.length; i++) {\n // If v is set to 0, this signifies that it was not possible to get a signature from this validator and we skip evaluation\n // (In a valid signature, it is either 27 or 28)\n if (_v[i] != 0) {\n // Check that the current validator has signed off on the hash\n require(\n verifySig(\n _currentValidators[i],\n _theHash,\n _v[i],\n _r[i],\n _s[i]\n ),\n \"Validator signature does not match.\"\n );\n\n if (_currentValidators.length < 10 && _currentValidators[i] == owner()) {\n // If the validator set is less than 10 validators and the owner is one of them, we skip the power check\n // This is to allow the owner to update the valset without having to wait for the full validator set to sign off\n return;\n }\n\n // Sum up cumulative power\n cumulativePower = cumulativePower + _currentPowers[i];\n\n // Break early to avoid wasting gas\n if (cumulativePower > _powerThreshold) {\n break;\n }\n }\n }\n\n // Check that there was enough power\n require(\n cumulativePower > _powerThreshold,\n \"Submitted validator set signatures do not have enough power.\"\n );\n // Success\n }\n\n // This updates the valset by checking that the validators in the current valset have signed off on the\n // new valset. The signatures supplied are the signatures of the current valset over the checkpoint hash\n // generated from the new valset.\n // Anyone can call this function, but they must supply valid signatures of state_powerThreshold of the current valset over\n // the new valset.\n function updateValset(\n // The new version of the validator set\n ValsetArgs calldata _newValset,\n // The current validators that approve the change\n ValsetArgs calldata _currentValset,\n // These are arrays of the parts of the current validator's signatures\n uint8[] calldata _v,\n bytes32[] calldata _r,\n bytes32[] calldata _s\n ) external whenNotPaused {\n // CHECKS\n\n // Check that the valset nonce is greater than the old one\n require(\n _newValset.valsetNonce > _currentValset.valsetNonce,\n \"New valset nonce must be greater than the current nonce\"\n );\n\n // Check that current validators, powers, and signatures (v,r,s) set is well-formed\n require(\n _currentValset.validators.length == _currentValset.powers.length &&\n _currentValset.validators.length == _v.length &&\n _currentValset.validators.length == _r.length &&\n _currentValset.validators.length == _s.length,\n \"Malformed current validator set\"\n );\n\n // Prevent insane jumps potentially leaving the contract unable to process further valset updates\n require(\n _newValset.valsetNonce <\n _currentValset.valsetNonce + MAX_NONCE_JUMP_LIMIT,\n \"New valset nonce must be less than 10_000_000_000_000 greater than the current nonce\"\n );\n\n // Check that the supplied current validator set matches the saved checkpoint\n require(\n makeCheckpoint(_currentValset, state_hyperionId) ==\n state_lastValsetCheckpoint,\n \"Supplied current validators and powers do not match checkpoint.\"\n );\n\n // Check that enough current validators have signed off on the new validator set\n bytes32 newCheckpoint = makeCheckpoint(_newValset, state_hyperionId);\n checkValidatorSignatures(\n _currentValset.validators,\n _currentValset.powers,\n _v,\n _r,\n _s,\n newCheckpoint,\n state_powerThreshold\n );\n\n _validateValidatorSet(\n _newValset.validators,\n _newValset.powers,\n state_powerThreshold\n );\n\n // ACTIONS\n\n // Stored to be used next time to validate that the valset\n // supplied by the caller is correct.\n state_lastValsetCheckpoint = newCheckpoint;\n\n // Store new nonce\n state_lastValsetNonce = _newValset.valsetNonce;\n\n // Store new valset height\n state_lastValsetHeight = getBlockNumber();\n\n // Send submission reward to msg.sender if reward token is a valid value\n if (\n _newValset.rewardToken != address(0) && _newValset.rewardAmount != 0\n ) {\n IERC20(_newValset.rewardToken).safeTransfer(\n msg.sender,\n _newValset.rewardAmount\n );\n }\n\n // LOGS\n state_lastEventNonce = state_lastEventNonce + 1;\n state_lastEventHeight = getBlockNumber();\n emit ValsetUpdatedEvent(\n _newValset.valsetNonce,\n state_lastEventNonce,\n _newValset.rewardAmount,\n _newValset.rewardToken,\n _newValset.validators,\n _newValset.powers\n );\n }\n\n // submitBatch processes a batch of Helios -> Ethereum transactions by sending the tokens in the transactions\n // to the destination addresses. It is approved by the current Helios validator set.\n // Anyone can call this function, but they must supply valid signatures of state_powerThreshold of the current valset over\n // the batch.\n function submitBatch(\n // The validators that approve the batch\n ValsetArgs memory _currentValset,\n // These are arrays of the parts of the validators signatures\n uint8[] memory _v,\n bytes32[] memory _r,\n bytes32[] memory _s,\n // The batch of transactions\n uint256[] memory _amounts,\n address[] memory _destinations,\n uint256[] memory _fees,\n uint256 _batchNonce,\n address _tokenContract,\n // a block height beyond which this batch is not valid\n // used to provide a fee-free timeout\n uint256 _batchTimeout\n ) external nonReentrant whenNotPaused {\n // CHECKS scoped to reduce stack depth\n {\n // Check that the batch nonce is higher than the last nonce for this token\n require(\n state_lastBatchNonces[_tokenContract] < _batchNonce,\n \"New batch nonce must be greater than the current nonce\"\n );\n\n // Prevent insane jumps potentially leaving the contract unable to process further batches\n require(\n _batchNonce <\n state_lastBatchNonces[_tokenContract] +\n MAX_NONCE_JUMP_LIMIT,\n \"New batch nonce must be less than 10_000_000_000_000 greater than the current nonce\"\n );\n\n // Check that the block height is less than the timeout height\n require(\n getBlockNumber() < _batchTimeout,\n \"Batch timeout must be greater than the current block height\"\n );\n\n // Check that current validators, powers, and signatures (v,r,s) set is well-formed\n require(\n _currentValset.validators.length ==\n _currentValset.powers.length &&\n _currentValset.validators.length == _v.length &&\n _currentValset.validators.length == _r.length &&\n _currentValset.validators.length == _s.length,\n \"Malformed current validator set\"\n );\n\n // Check that the supplied current validator set matches the saved checkpoint\n require(\n makeCheckpoint(_currentValset, state_hyperionId) ==\n state_lastValsetCheckpoint,\n \"Supplied current validators and powers do not match checkpoint.\"\n );\n\n // Check that the transaction batch is well-formed\n require(\n _amounts.length == _destinations.length &&\n _amounts.length == _fees.length,\n \"Malformed batch of transactions\"\n );\n\n // Check that enough current validators have signed off on the transaction batch and valset\n checkValidatorSignatures(\n _currentValset.validators,\n _currentValset.powers,\n _v,\n _r,\n _s,\n // Get hash of the transaction batch and checkpoint\n keccak256(\n abi.encode(\n state_hyperionId,\n // bytes32 encoding of \"transactionBatch\"\n 0x7472616e73616374696f6e426174636800000000000000000000000000000000,\n _amounts,\n _destinations,\n _fees,\n _batchNonce,\n _tokenContract,\n _batchTimeout\n )\n ),\n state_powerThreshold\n );\n\n // ACTIONS\n\n // Store batch nonce\n state_lastBatchNonces[_tokenContract] = _batchNonce;\n\n {\n // Send transaction amounts to destinations\n for (uint256 i = 0; i < _amounts.length; i++) {\n if (isHeliosNativeToken[_tokenContract]) {\n HeliosERC20(_tokenContract).mint(\n _destinations[i],\n _amounts[i]\n );\n } else {\n IERC20(_tokenContract).safeTransfer(\n _destinations[i],\n _amounts[i]\n );\n }\n }\n }\n }\n\n // LOGS scoped to reduce stack depth\n {\n state_lastEventNonce = state_lastEventNonce + 1;\n state_lastEventHeight = getBlockNumber();\n emit TransactionBatchExecutedEvent(\n _batchNonce,\n _tokenContract,\n state_lastEventNonce\n );\n }\n }\n\n function sendToHelios(\n address _tokenContract,\n bytes32 _destination,\n uint256 _amount,\n string calldata _data\n ) external whenNotPaused nonReentrant {\n uint256 transferAmount;\n\n if (isHeliosNativeToken[_tokenContract]) {\n HeliosERC20(_tokenContract).burn(msg.sender, _amount);\n\n transferAmount = _amount;\n\n state_lastEventNonce = state_lastEventNonce + 1;\n state_lastEventHeight = getBlockNumber();\n emit SendToHeliosEvent(\n _tokenContract,\n msg.sender,\n _destination,\n transferAmount,\n state_lastEventNonce,\n _data\n );\n } else {\n uint256 balanceBeforeTransfer = IERC20(_tokenContract).balanceOf(\n address(this)\n );\n\n IERC20(_tokenContract).safeTransferFrom(\n msg.sender,\n address(this),\n _amount\n );\n\n uint256 balanceAfterTransfer = IERC20(_tokenContract).balanceOf(\n address(this)\n );\n transferAmount = balanceAfterTransfer - balanceBeforeTransfer;\n\n state_lastEventNonce = state_lastEventNonce + 1;\n state_lastEventHeight = getBlockNumber();\n uint8 decimalsValue = IERC20Metadata(_tokenContract).decimals();\n\n emit SendToHeliosEvent(\n _tokenContract,\n msg.sender,\n _destination,\n transferAmount,\n state_lastEventNonce,\n string(abi.encodePacked(\n \"{\",\n \"\\\"metadata\\\": {\",\n \"\\\"symbol\\\": \\\"\", IERC20Metadata(_tokenContract).symbol(), \"\\\",\",\n \"\\\"name\\\": \\\"\", IERC20Metadata(_tokenContract).name(), \"\\\",\",\n \"\\\"decimals\\\": \", uint2str(decimalsValue), \n \"},\",\n \"\\\"data\\\": \", bytes(_data).length > 0 ? _data : \"\\\"\\\"\",\n \"}\"\n ))\n );\n }\n }\n\n function deployERC20(\n string calldata _heliosDenom,\n string calldata _name,\n string calldata _symbol,\n uint8 _decimals\n ) external {\n HeliosERC20 erc20 = new HeliosERC20(_name, _symbol, _decimals);\n isHeliosNativeToken[address(erc20)] = true;\n\n // Fire an event to let the Hyperion module know\n state_lastEventNonce = state_lastEventNonce + 1;\n state_lastEventHeight = getBlockNumber();\n emit ERC20DeployedEvent(\n _heliosDenom,\n address(erc20),\n _name,\n _symbol,\n _decimals,\n state_lastEventNonce\n );\n }\n\n /** Testnet only */\n function testnetWithdraw(\n address _tokenContract,\n uint256 _amount\n ) external onlyOwner {\n if (isHeliosNativeToken[_tokenContract]) {\n HeliosERC20(_tokenContract).mint(msg.sender, _amount);\n } else if (_tokenContract == address(0)) {\n payable(msg.sender).transfer(address(this).balance);\n } else {\n IERC20(_tokenContract).safeTransfer(msg.sender, _amount);\n }\n }\n\n function transferTokenOwnership(address _tokenContract, address _newOwner) external onlyOwner {\n if (isHeliosNativeToken[_tokenContract]) {\n HeliosERC20(_tokenContract).transferOwnership(_newOwner);\n }\n }\n\n /** Testing */\n function deployERC20WithSupply(\n string calldata,\n string calldata _name,\n string calldata _symbol,\n uint8 _decimals,\n uint256 supply\n ) external {\n HeliosERC20 erc20 = new HeliosERC20(_name, _symbol, _decimals);\n erc20.mint(msg.sender, supply);\n }\n\n function getBlockNumber() public view returns (uint256) {\n // Arbitrum only\n if (state_hyperionId == 0x000000000000000000000000000000000000000000000000000000000000a4b1) {\n return ArbSys(0x0000000000000000000000000000000000000064).arbBlockNumber();\n } else {\n return block.number;\n }\n }\n\n function emergencyPause() external onlyOwner {\n _pause();\n }\n\n function emergencyUnpause() external onlyOwner {\n _unpause();\n }\n\n function uint2str(uint256 _i) internal pure returns (string memory) {\n if (_i == 0) {\n return \"0\";\n }\n uint256 j = _i;\n uint256 len;\n while (j != 0) {\n len++;\n j /= 10;\n }\n bytes memory bstr = new bytes(len);\n uint256 k = len;\n while (_i != 0) {\n bstr[--k] = bytes1(uint8(48 + _i % 10));\n _i /= 10;\n }\n return string(bstr);\n }\n}\n"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 1000000
},
"metadata": {
"useLiteralContent": true
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"abi",
"evm.bytecode",
"evm.deployedBytecode",
"evm.methodIdentifiers",
"metadata",
"devdoc",
"userdoc",
"storageLayout",
"evm.gasEstimates"
],
"": [
"ast"
]
}
}
}
}