019d5666-71a5-72ca-9f63-c22da967b9db
Open this run to answer one question: is this real attacker-relevant behavior with real impact, or just normal contract plumbing?
| ID | Type | Status | Attempts | Heartbeat |
|---|---|---|---|---|
| 42743 | artifact.fetch | complete | 1 / 3 | 1 week ago |
| 42744 | proxy.resolve | complete | 1 / 3 | 1 week ago |
| 42745 | tool.cast_disasm | complete | 1 / 3 | 1 week ago |
| 42746 | analysis.bundle | complete | 1 / 3 | 1 week ago |
| 42747 | capability.graph | complete | 1 / 3 | 1 week ago |
| 42748 | detector.run | complete | 1 / 3 | 1 week ago |
| 42749 | validation.fork | complete | 1 / 3 | 1 week ago |
| 42920 | report.consolidate | complete | 1 / 6 | 1 week ago |
| 42921 | tool.slither | complete | 1 / 2 | 1 week ago |
{
"status": "not_proxy"
}
'forge clean' running (wd: /tmp/slither-y5vnqpje) 'forge config --json' running 'forge build --build-info --skip ./test/** ./script/** --force' running (wd: /tmp/slither-y5vnqpje) Crowdsale (contracts/Contract.sol#570-870) contract sets array length with a user-controlled value: - rounds.push(genRound) (contracts/Contract.sol#676) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#array-length-assignment Reentrancy in Crowdsale.buyTokens(address) (contracts/Contract.sol#698-728): External calls: - _processPurchase(beneficiary,tokens) (contracts/Contract.sol#718-720) - _token.safeTransfer(beneficiary,tokenAmount) (contracts/Contract.sol#766) - (success,returndata) = address(token).call(data) (contracts/Contract.sol#402-403) External calls sending eth: - _forwardFunds() (contracts/Contract.sol#722-723) - _walletA.transfer(walletAmountA) (contracts/Contract.sol#802) - _walletB.transfer(walletAmountB) (contracts/Contract.sol#807) - _walletC.transfer(walletAmountC) (contracts/Contract.sol#810) State variables written after the call(s): - roundDetails[currentRound].amountReached = roundDetails[currentRound].amountReached.add(weiAmount) (contracts/Contract.sol#725-728) Crowdsale.roundDetails (contracts/Contract.sol#581-583) can be used in cross function reentrancies: - Crowdsale._checkRoundValidity(address,uint256) (contracts/Contract.sol#633-644) - Crowdsale._updateRound() (contracts/Contract.sol#601-633) - Crowdsale.addRound(uint256,uint256,uint256,uint256,uint256) (contracts/Contract.sol#821-826) - Crowdsale.buyTokens(address) (contracts/Contract.sol#698-728) - Crowdsale.constructor(IERC20,address,uint256,address,uint256,address,uint256) (contracts/Contract.sol#661-676) - Crowdsale.roundDetails (contracts/Contract.sol#581-583) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities Crowdsale.withdrawTokens(IERC20,address) (contracts/Contract.sol#854-862) ignores return value by token_.transfer(beneficiary_,balance) (contracts/Contract.sol#859-862) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unchecked-transfer Crowdsale._forwardFunds() (contracts/Contract.sol#796-817) ignores return value by _weiDistributed.add(currentFunds) (contracts/Contract.sol#810-811) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#unused-return Crowdsale.constructor(IERC20,address,uint256,address,uint256,address,uint256).token (contracts/Contract.sol#662) shadows: - Crowdsale.token() (contracts/Contract.sol#686-689) (function) GHCCrowdsale.constructor(IERC20,address,uint256,address,uint256,address,uint256).token (contracts/Contract.sol#1052) shadows: - Crowdsale.token() (contracts/Contract.sol#686-689) (function) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#local-variable-shadowing Crowdsale.withdrawETH(address).beneficiary_ (contracts/Contract.sol#862-863) lacks a zero-check on : - beneficiary_.transfer(balance) (contracts/Contract.sol#869-870) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#missing-zero-address-validation Reentrancy in Crowdsale.buyTokens(address) (contracts/Contract.sol#698-728): External calls: - _processPurchase(beneficiary,tokens) (contracts/Contract.sol#718-720) - _token.safeTransfer(beneficiary,tokenAmount) (contracts/Contract.sol#766) - (success,returndata) = address(token).call(data) (contracts/Contract.sol#402-403) Event emitted after the call(s): - TokensPurchased(_msgSender(),beneficiary,weiAmount,tokens) (contracts/Contract.sol#720-721) Reentrancy in Crowdsale.buyTokens(address) (contracts/Contract.sol#698-728): External calls: - _processPurchase(beneficiary,tokens) (contracts/Contract.sol#718-720) - _token.safeTransfer(beneficiary,tokenAmount) (contracts/Contract.sol#766) - (success,returndata) = address(token).call(data) (contracts/Contract.sol#402-403) External calls sending eth: - _forwardFunds() (contracts/Contract.sol#722-723) - _walletA.transfer(walletAmountA) (contracts/Contract.sol#802) - _walletB.transfer(walletAmountB) (contracts/Contract.sol#807) - _walletC.transfer(walletAmountC) (contracts/Contract.sol#810) Event emitted after the call(s): - FundsDistributed(_walletA,walletAmountA,_walletB,walletAmountB,_walletC,walletAmountC) (contracts/Contract.sol#811-816) - _forwardFunds() (contracts/Contract.sol#722-723) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-3 Crowdsale._updateRound() (contracts/Contract.sol#601-633) uses timestamp for comparisons Dangerous comparisons: - rounds[currentRound].stopTime < block.timestamp && rounds.length > nextRound (contracts/Contract.sol#603-606) - rounds[currentRound].stopTime < block.timestamp && rounds.length > currentRound + 1 && rounds[currentRound].roundCap <= roundDetails[currentRound].amountReached (contracts/Contract.sol#627-630) Crowdsale._checkRoundValidity(address,uint256) (contracts/Contract.sol#633-644) uses timestamp for comparisons Dangerous comparisons: - require(bool,string)(block.timestamp <= rounds[currentRound].stopTime,GHCCrowdale: crowdsale stopped) (contracts/Contract.sol#634) - require(bool,string)(block.timestamp >= rounds[currentRound].startTime,GHCCrowdale: crowdsale not started) (contracts/Contract.sol#635-637) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#block-timestamp Address.isContract(address) (contracts/Contract.sol#285-298) uses assembly - INLINE ASM (contracts/Contract.sol#296-297) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#assembly-usage 2 different versions of Solidity are used: - Version constraint ^0.5.0 is used by: -^0.5.0 (contracts/Contract.sol#2-3) -^0.5.0 (contracts/Contract.sol#31) -^0.5.0 (contracts/Contract.sol#107) -^0.5.0 (contracts/Contract.sol#334) -^0.5.0 (contracts/Contract.sol#409) -^0.5.0 (contracts/Contract.sol#485) -^0.5.0 (contracts/Contract.sol#541) -^0.5.0 (contracts/Contract.sol#871) -^0.5.0 (contracts/Contract.sol#908-909) -^0.5.0 (contracts/Contract.sol#945-947) -^0.5.0 (contracts/Contract.sol#1021) - Version constraint ^0.5.5 is used by: -^0.5.5 (contracts/Contract.sol#259-261) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#different-pragma-directives-are-used Context._msgData() (contracts/Contract.sol#22-27) is never used and should be removed Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#dead-code Version constraint ^0.5.0 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html) - DirtyBytesArrayToStorage - ABIDecodeTwoDimensionalArrayMemory - KeccakCaching - EmptyByteArrayCopy - DynamicArrayCleanup - ImplicitConstructorCallvalueCheck - TupleAssignmentMultiStackSlotComponents - MemoryArrayCreationOverflow - privateCanBeOverridden - SignedArrayStorageCopy - ABIEncoderV2StorageArrayWithMultiSlotElement - DynamicConstructorArgumentsClippedABIV2 - UninitializedFunctionPointerInConstructor - IncorrectEventSignatureInLibraries - ABIEncoderV2PackedStorage. It is used by: - ^0.5.0 (contracts/Contract.sol#2-3) - ^0.5.0 (contracts/Contract.sol#31) - ^0.5.0 (contracts/Contract.sol#107) - ^0.5.0 (contracts/Contract.sol#334) - ^0.5.0 (contracts/Contract.sol#409) - ^0.5.0 (contracts/Contract.sol#485) - ^0.5.0 (contracts/Contract.sol#541) - ^0.5.0 (contracts/Contract.sol#871) - ^0.5.0 (contracts/Contract.sol#908-909) - ^0.5.0 (contracts/Contract.sol#945-947) - ^0.5.0 (contracts/Contract.sol#1021) Version constraint ^0.5.5 contains known severe issues (https://solidity.readthedocs.io/en/latest/bugs.html) - DirtyBytesArrayToStorage - ABIDecodeTwoDimensionalArrayMemory - KeccakCaching - EmptyByteArrayCopy - DynamicArrayCleanup - ImplicitConstructorCallvalueCheck - TupleAssignmentMultiStackSlotComponents - MemoryArrayCreationOverflow - privateCanBeOverridden - SignedArrayStorageCopy - ABIEncoderV2StorageArrayWithMultiSlotElement - DynamicConstructorArgumentsClippedABIV2 - UninitializedFunctionPointerInConstructor - IncorrectEventSignatureInLibraries - ABIEncoderV2PackedStorage - IncorrectByteInstructionOptimization - DoubleShiftSizeOverflow. It is used by: - ^0.5.5 (contracts/Contract.sol#259-261) solc-0.5.5 is an outdated solc version. Use a more recent version (at least 0.8.0), if possible. Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#incorrect-versions-of-solidity Low level call in Address.sendValue(address,uint256) (contracts/Contract.sol#326-333): - (success,None) = recipient.call.value(amount)() (contracts/Contract.sol#329) Low level call in SafeERC20.callOptionalReturn(IERC20,bytes) (contracts/Contract.sol#389-408): - (success,returndata) = address(token).call(data) (contracts/Contract.sol#402-403) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#low-level-calls Parameter Crowdsale.addRound(uint256,uint256,uint256,uint256,uint256)._duration (contracts/Contract.sol#822) is not in mixedCase Parameter Crowdsale.addRound(uint256,uint256,uint256,uint256,uint256)._cap (contracts/Contract.sol#822) is not in mixedCase Parameter Crowdsale.addRound(uint256,uint256,uint256,uint256,uint256)._rate (contracts/Contract.sol#822) is not in mixedCase Parameter Crowdsale.addRound(uint256,uint256,uint256,uint256,uint256)._max (contracts/Contract.sol#822) is not in mixedCase Parameter Crowdsale.addRound(uint256,uint256,uint256,uint256,uint256)._min (contracts/Contract.sol#822) is not in mixedCase Variable Crowdsale.HOUR_TO_SECOND (contracts/Contract.sol#571-572) is not in mixedCase Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#conformance-to-solidity-naming-conventions Redundant expression "this (contracts/Contract.sol#25)" inContext (contracts/Contract.sol#13-27) Redundant expression "this (contracts/Contract.sol#751)" inCrowdsale (contracts/Contract.sol#570-870) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#redundant-statements Reentrancy in Crowdsale._forwardFunds() (contracts/Contract.sol#796-817): External calls: - _walletA.transfer(walletAmountA) (contracts/Contract.sol#802) - _walletB.transfer(walletAmountB) (contracts/Contract.sol#807) - _walletC.transfer(walletAmountC) (contracts/Contract.sol#810) Event emitted after the call(s): - FundsDistributed(_walletA,walletAmountA,_walletB,walletAmountB,_walletC,walletAmountC) (contracts/Contract.sol#811-816) Reentrancy in Crowdsale.buyTokens(address) (contracts/Contract.sol#698-728): External calls: - _forwardFunds() (contracts/Contract.sol#722-723) - _walletA.transfer(walletAmountA) (contracts/Contract.sol#802) - _walletB.transfer(walletAmountB) (contracts/Contract.sol#807) - _walletC.transfer(walletAmountC) (contracts/Contract.sol#810) State variables written after the call(s): - roundDetails[currentRound].amountReached = roundDetails[currentRound].amountReached.add(weiAmount) (contracts/Contract.sol#725-728) Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#reentrancy-vulnerabilities-4 Crowdsale.HOUR_TO_SECOND (contracts/Contract.sol#571-572) should be constant Crowdsale._weiDistributed (contracts/Contract.sol#589-590) should be constant Reference: https://github.com/crytic/slither/wiki/Detector-Documentation#state-variables-that-could-be-declared-constant . analyzed (13 contracts with 100 detectors), 31 result(s) found
{
"solc": {
"status": "ok",
"use_rc": 0,
"version": "0.5.5",
"strategy": "solc-select",
"solc_path": "/var/www/tripwire/.venv/bin/solc",
"install_rc": 0,
"use_stderr": null,
"use_stdout": "Switched global version to 0.5.5",
"install_stderr": null,
"install_stdout": "Version '0.5.5' is already installed, skipping..."
},
"solc_args": "--base-path /tmp/slither-y5vnqpje --allow-paths /tmp/slither-y5vnqpje,/tmp/slither-y5vnqpje/lib,/tmp/slither-y5vnqpje/src",
"remappings": [],
"source_files": [
"contracts/Contract.sol"
],
"contract_count": 0,
"contract_names": [],
"detector_count": 31,
"workspace_hash": "a3d7867d212ca96998e05640529c7284b785b88999c6ec7f4bdb483317caf3e7",
"duration_seconds": 0.8844010829925537,
"solc_version_requested": "0.5.8"
}
{"no_findings":false,"summary":"The first-party crowdsale logic has broken ETH distribution accounting, broken per-address contribution accounting, and a reentrancy-prone purchase flow that updates round state after external token delivery.","findings":[{"severity":"high","category":"other","title":"ETH distribution accounting is never persisted, so crossing the payout threshold can brick subsequent purchases","exploit_scenario":"Once total raised ETH reaches `_triggerAmount`, `_forwardFunds()` distributes the full `currentFunds` balance to the three wallets. Because `_weiDistributed` is not assigned back, it stays `0`. On the next purchase, `currentFunds` is recalculated as the cumulative `_weiRaised`, not the undistributed amount, so the function attempts to pay out more ETH than the contract actually holds and the purchase reverts. Any buyer can be the one who pushes the sale over the threshold and trigger this broken state.","recommendation":"Persist the distribution state with `_weiDistributed = _weiDistributed.add(currentFunds);` before returning, and add tests that cover multiple payout cycles after several purchases.","evidence":"`currentFunds` is derived from `_weiRaised.sub(_weiDistributed)`, but line 827 calls `_weiDistributed.add(currentFunds);` without storing the result. The contract therefore forgets every prior distribution.","locations":["contracts/Contract.sol:818","contracts/Contract.sol:821","contracts/Contract.sol:823","contracts/Contract.sol:825","contracts/Contract.sol:827"]},{"severity":"medium","category":"other","title":"Per-address round contribution caps are unenforced because contributor totals are never updated","exploit_scenario":"A buyer can split a large purchase into many transactions and exceed the advertised `maxContibution` for the round. `_checkRoundValidity()` checks `roundDetails[currentRound].contributors[_contributor] + _amount`, but that mapping is never incremented anywhere in the purchase flow, so each call is validated as if the sender had contributed `0` previously.","recommendation":"Update `roundDetails[currentRound].contributors[beneficiary or msg.sender]` during the purchase flow before external interactions, and add tests that assert cumulative per-round limits across multiple transactions.","evidence":"The limit check reads `contributors[_contributor]` at line 648, but `_updatePurchasingState()` is empty and no other code writes to the `contributors` mapping.","locations":["contracts/Contract.sol:648","contracts/Contract.sol:740","contracts/Contract.sol:801"]},{"severity":"medium","category":"reentrancy","title":"buyTokens performs external token delivery before round accounting and lacks the advertised reentrancy guard","exploit_scenario":"If the sale token is ERC777-like or otherwise invokes a callback during `transfer`, a contract beneficiary can reenter `buyTokens` from that callback with additional ETH. Because `roundDetails[currentRound].amountReached` and the contributor mapping are only updated after `_deliverTokens`, the nested call sees stale round state and can bypass round-cap and per-address-limit checks within the same transaction.","recommendation":"Mark `buyTokens` as `nonReentrant` and move round accounting updates ahead of `_processPurchase()` so all cap checks observe committed state before any external call.","evidence":"The function comment says `buyTokens` has a non-reentrancy guard, but no `nonReentrant` modifier is present. `_processPurchase()` calls `_token.safeTransfer(...)` before `amountReached` is incremented at line 746.","locations":["contracts/Contract.sol:721","contracts/Contract.sol:725","contracts/Contract.sol:737","contracts/Contract.sol:746","contracts/Contract.sol:781"]}]}
OpenAI Codex v0.118.0 (research preview)
--------
workdir: /tmp/codex-_rc4ifnk
model: gpt-5.4
provider: openai
approval: never
sandbox: read-only
reasoning effort: high
reasoning summaries: none
session id: 019d566b-594f-7383-ae9c-6ba6abc351c2
--------
user
You are a security auditor. Audit this Solidity codebase for exploitable vulnerabilities.
Focus on: reentrancy, access control, upgradeability/proxy issues, signature validation, oracle manipulation,
accounting/invariant breaks, external call patterns, unchecked return values, and dangerous delegatecall.
Scope rules:
- You MUST fully read `AUDIT_BUNDLE.txt` before concluding. It contains the complete contents of all first-party Solidity sources in this workspace.
- Treat `lib/` and `@openzeppelin/` as third-party dependencies; skip them unless there is a concrete misuse angle in first-party code.
- If there are only dependency files and no first-party sources, set no_findings=true and explain in summary.
Output MUST be valid JSON matching the provided schema.
- If you find nothing meaningful: set no_findings=true and findings=[].
- Otherwise: set no_findings=false and include findings with severity/category/title and file/line locations when possible.
Output constraints (IMPORTANT):
- severity MUST be exactly one of: info, low, medium, high, critical (lowercase).
- category MUST be exactly one of: access_control, reentrancy, math, oracle, upgradeability, auth, other.
Keep summary short and concrete.
warning: Codex could not find system bubblewrap on PATH. Please install bubblewrap with your package manager. Codex will use the vendored bubblewrap in the meantime.
exec
/bin/bash -lc 'pwd && ls -la && rg --files' in /tmp/codex-_rc4ifnk
succeeded in 0ms:
/tmp/codex-_rc4ifnk
total 80
drwx------ 3 noahkuhn noahkuhn 4096 Apr 4 02:56 .
drwxrwxrwt 250 nobody nogroup 24576 Apr 4 02:56 ..
-rw-rw-r-- 1 noahkuhn noahkuhn 39724 Apr 4 02:56 AUDIT_BUNDLE.txt
-rw-rw-r-- 1 noahkuhn noahkuhn 815 Apr 4 02:56 codex-output-schema.json
drwxrwxr-x 2 noahkuhn noahkuhn 4096 Apr 4 02:56 contracts
codex-output-schema.json
AUDIT_BUNDLE.txt
contracts/Contract.sol
Reading the bundled first-party Solidity sources first, then I’ll inspect the contract in context and extract any exploitable findings with concrete locations.
→ Read AUDIT_BUNDLE.txt completely
• Analyze first-party contract logic for exploitable issues
• Produce JSON findings with evidence and locations
exec
/bin/bash -lc "wc -l AUDIT_BUNDLE.txt && sed -n '1,220p' AUDIT_BUNDLE.txt && printf '\\n---CHUNK-END---\\n' && sed -n '221,440p' AUDIT_BUNDLE.txt && printf '\\n---CHUNK-END---\\n' && sed -n '441,660p' AUDIT_BUNDLE.txt" in /tmp/codex-_rc4ifnk
succeeded in 0ms:
1092 AUDIT_BUNDLE.txt
This file concatenates the full contents of first-party Solidity sources for auditing.
Do not treat dependency code under lib/ or @openzeppelin/ as first-party.
================================================================================
FILE: contracts/Contract.sol
================================================================================
// File: contracts/GSN/Context.sol
pragma solidity ^0.5.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with GSN meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
contract Context {
// Empty internal constructor, to prevent people from mistakenly deploying
// an instance of this contract, which should be used via inheritance.
constructor () internal { }
// solhint-disable-previous-line no-empty-blocks
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
// File: contracts/token/ERC20/IERC20.sol
pragma solidity ^0.5.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP. Does not include
* the optional functions; to access them see {ERC20Detailed}.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}
// File: contracts/math/SafeMath.sol
pragma solidity ^0.5.0;
/**
* @dev Wrappers over Solidity's arithmetic operations with added overflow
* checks.
*
* Arithmetic operations in Solidity wrap on overflow. This can easily result
* in bugs, because programmers usually assume that an overflow raises an
* error, which is the standard behavior in high level programming languages.
* `SafeMath` restores this intuition by reverting the transaction when an
* operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
* - Subtraction cannot overflow.
*
* _Available since v2.4.0._
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts with custom message on
---CHUNK-END---
* 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.
*
* _Available since v2.4.0._
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message 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.
*
* _Available since v2.4.0._
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
// File: contracts/utils/Address.sol
pragma solidity ^0.5.5;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != accountHash && codehash != 0x0);
}
/**
* @dev Converts an `address` into `address payable`. Note that this is
* simply a type cast: the actual underlying value is not changed.
*
* _Available since v2.4.0._
*/
function toPayable(address account) internal pure returns (address payable) {
return address(uint160(account));
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*
* _Available since v2.4.0._
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-call-value
(bool success, ) = recipient.call.value(amount)("");
require(success, "Address: unable to send value, recipient may have reverted");
}
}
// File: contracts/token/ERC20/SafeERC20.sol
pragma solidity ^0.5.0;
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves.
// A Solidity high level call has three parts:
// 1. The target address is checked to verify it contains contract code
// 2. The call itself is made, and success asserted
// 3. The return value is decoded, which in turn checks the size of the returned data.
// solhint-disable-next-line max-line-length
require(address(token).isContract(), "SafeERC20: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = address(token).call(data);
require(success, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// File: contracts/ownership/Ownable.sol
pragma solidity ^0.5.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
contract Ownable is Context {
address private _owner;
---CHUNK-END---
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(isOwner(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Returns true if the caller is the current owner.
*/
function isOwner() public view returns (bool) {
return _msgSender() == _owner;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
*/
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
// File: contracts/utils/ReentrancyGuard.sol
pragma solidity ^0.5.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].
*
* _Since v2.5.0:_ this module is now much more gas efficient, given net gas
* metering changes introduced in the Istanbul hardfork.
*/
contract ReentrancyGuard {
bool private _notEntered;
constructor () internal {
// Storing an initial 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 percetange 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.
_notEntered = true;
}
/**
* @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(_notEntered, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_notEntered = false;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_notEntered = true;
}
}
// File: contracts/crowdsale/Crowdsale.sol
pragma solidity ^0.5.0;
/**
* @title Crowdsale
* @dev Crowdsale is a base contract for managing a token crowdsale,
* allowing investors to purchase tokens with ether. This contract implements
* such functionality in its most fundamental form and can be extended to provide additional
* functionality and/or custom behavior.
* The external interface represents the basic interface for purchasing tokens, and conforms
* the base architecture for crowdsales. It is *not* intended to be modified / overridden.
* The internal interface conforms the extensible and modifiable surface of crowdsales. Override
* the methods to add functionality. Consider using 'super' where appropriate to concatenate
* behavior.
*/
contract Crowdsale is Context, ReentrancyGuard, Ownable {
using SafeMath for uint256;
using SafeERC20 for IERC20;
uint256 private HOUR_TO_SECOND = 3600;
// GHC Custom Logic
struct Round {
uint256 startTime;
uint256 stopTime;
uint256 duration;
uint256 roundCap;
uint256 rate; // in ETH
uint256 maxContibution; // in ETH
uint256 minContibution; // in ETH
}
struct RoundDetails {
uint256 amountReached;
mapping (address => uint256) contributors;
}
event FundsDistributed(address walletA,uint256 amountA, address walletB,uint256 amountB, address walletC, uint256 amountC);
Round[] public rounds;
RoundDetails[] public roundDetails;
uint256 public currentRound=0;
// The token being sold
IERC20 private _token;
uint256 private _weiRaised;
uint256 private _weiDistributed;
address payable private _walletA;
address payable private _walletB;
address payable private _walletC;
// Amount when reached to distribute funds
uint256 private _triggerAmount = 20*10**18;
mapping (address => uint256) public walletProportion;
function _updateRound() internal {
uint256 nextRound = currentRound+1;
if (rounds[currentRound].stopTime < block.timestamp && rounds.length > nextRound) {
// has new round in queue
currentRound++;
rounds[currentRound].startTime = block.timestamp + HOUR_TO_SECOND*72;
rounds[currentRound].stopTime = rounds[currentRound].startTime + rounds[currentRound].duration;
// add prev. unused tokens to next pool
if (currentRound>1){
rounds[currentRound].roundCap = rounds[currentRound].roundCap + rounds[currentRound-1].roundCap - roundDetails[currentRound-1].amountReached;
}
}
else if (rounds[currentRound].stopTime < block.timestamp && rounds.length > currentRound+1 && rounds[currentRound].roundCap <= roundDetails[currentRound].amountReached) {
currentRound++;
rounds[currentRound].startTime = block.timestamp + HOUR_TO_SECOND*12;
rounds[currentRound].stopTime = rounds[currentRound].startTime + rounds[currentRound].duration;
}
}
function _checkRoundValidity(address _contributor, uint256 _amount) internal view {
require(block.timestamp <= rounds[currentRound].stopTime,"GHCCrowdale: crowdsale stopped");
require(block.timestamp >= rounds[currentRound].startTime,"GHCCrowdale: crowdsale not started");
require(roundDetails[currentRound].amountReached + _amount <= rounds[currentRound].roundCap, "GHCCrowdale: round amount oveflow");
require(roundDetails[currentRound].contributors[_contributor]+_amount <= rounds[currentRound].maxContibution, "GHCCrowdale: max amount reached for round");
require(_amount >= rounds[currentRound].minContibution, "GHCCrowdale: max amount reached for round");
}
// // How many token units a buyer gets per wei.
// // The rate is the conversion between wei and the smallest and indivisible token unit.
// // So, if you are using a rate of 1 with a ERC20Detailed token with 3 decimals called TOK
exec
/bin/bash -lc "sed -n '661,880p' AUDIT_BUNDLE.txt && printf '\\n---CHUNK-END---\\n' && sed -n '881,1092p' AUDIT_BUNDLE.txt" in /tmp/codex-_rc4ifnk
succeeded in 0ms:
// // 1 wei will give you 1 unit, or 0.001 TOK.
// uint256 private _rate;
// // Amount of wei raised
// uint256 private _weiRaised;
/**
* Event for token purchase logging
* @param purchaser who paid for the tokens
* @param beneficiary who got the tokens
* @param value weis paid for purchase
* @param amount amount of tokens purchased
*/
event TokensPurchased(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
/**
* @dev The rate is the conversion between wei and the smallest and indivisible
* token unit. So, if you are using a rate of 1 with a ERC20Detailed token
* with 3 decimals called TOK, 1 wei will give you 1 unit, or 0.001 TOK.
* @param token Address of the token being sold
*/
constructor (IERC20 token, address payable walletA, uint256 proportionA, address payable walletB, uint256 proportionB, address payable walletC, uint256 proportionC) public {
require(address(token) != address(0), "Crowdsale: token is the zero address");
require(proportionA+proportionB+proportionC==100, "Crowdsale: 100% funds need to be distributed");
_token = token;
_walletA=walletA;
walletProportion[_walletA]=proportionA;
_walletB=walletB;
walletProportion[_walletB]=proportionB;
_walletC=walletC;
walletProportion[_walletC]=proportionC;
Round memory genRound = Round(0,0,0,0,0,0,0);
RoundDetails memory genRoundDetails = RoundDetails(0);
rounds.push(genRound);
roundDetails.push(genRoundDetails);
}
/**
* @dev fallback function ***DO NOT OVERRIDE***
* Note that other contracts will transfer funds with a base gas stipend
* of 2300, which is not enough to call buyTokens. Consider calling
* buyTokens directly when purchasing tokens from a contract.
*/
function () external payable {
buyTokens(_msgSender());
}
/**
* @return the token being sold.
*/
function token() public view returns (IERC20) {
return _token;
}
/**
* @return the amount of wei raised.
*/
function weiRaised() public view returns (uint256) {
return _weiRaised;
}
/**
* @dev low level token purchase ***DO NOT OVERRIDE***
* This function has a non-reentrancy guard, so it shouldn't be called by
* another `nonReentrant` function.
* @param beneficiary Recipient of the token purchase
*/
function buyTokens(address beneficiary) public payable {
_updateRound();
_checkRoundValidity(msg.sender, msg.value);
uint256 weiAmount = msg.value;
_preValidatePurchase(beneficiary, weiAmount);
// calculate token amount to be created // Change token amount from 18 decimal
uint256 tokens = _getTokenAmount(weiAmount);
// update state
_weiRaised = _weiRaised.add(weiAmount);
_processPurchase(beneficiary, tokens);
emit TokensPurchased(_msgSender(), beneficiary, weiAmount, tokens);
_updatePurchasingState(beneficiary, weiAmount);
_forwardFunds();
_postValidatePurchase(beneficiary, weiAmount);
// update currentRound amountReached
roundDetails[currentRound].amountReached = roundDetails[currentRound].amountReached.add(weiAmount);
}
/**
* @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met.
* Use `super` in contracts that inherit from Crowdsale to extend their validations.
* Example from CappedCrowdsale.sol's _preValidatePurchase method:
* super._preValidatePurchase(beneficiary, weiAmount);
* require(weiRaised().add(weiAmount) <= cap);
* @param beneficiary Address performing the token purchase
* @param weiAmount Value in wei involved in the purchase
*/
function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
require(beneficiary != address(0), "Crowdsale: beneficiary is the zero address");
require(weiAmount != 0, "Crowdsale: weiAmount is 0");
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
}
/**
* @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid
* conditions are not met.
* @param beneficiary Address performing the token purchase
* @param weiAmount Value in wei involved in the purchase
*/
function _postValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
// solhint-disable-previous-line no-empty-blocks
}
/**
* @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends
* its tokens.
* @param beneficiary Address performing the token purchase
* @param tokenAmount Number of tokens to be emitted
*/
function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
_token.safeTransfer(beneficiary, tokenAmount);
}
/**
* @dev Executed when a purchase has been validated and is ready to be executed. Doesn't necessarily emit/send
* tokens.
* @param beneficiary Address receiving the tokens
* @param tokenAmount Number of tokens to be purchased
*/
function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
_deliverTokens(beneficiary, tokenAmount);
}
/**
* @dev Override for extensions that require an internal state to check for validity (current user contributions,
* etc.)
* @param beneficiary Address receiving the tokens
* @param weiAmount Value in wei involved in the purchase
*/
function _updatePurchasingState(address beneficiary, uint256 weiAmount) internal {
// solhint-disable-previous-line no-empty-blocks
}
/**
* @dev Override to extend the way in which ether is converted to tokens.
* @param weiAmount Value in wei to be converted into tokens
* @return Number of tokens that can be purchased with the specified _weiAmount
*/
function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
return weiAmount.mul(rounds[currentRound].rate);
}
/**
* @dev Determines how ETH is stored/forwarded on purchases.
*/
function _forwardFunds() internal {
uint256 currentFunds = _weiRaised.sub(_weiDistributed);
if (currentFunds >= _triggerAmount) {
uint256 walletAmountA = walletProportion[_walletA].mul(currentFunds).div(100);
if (walletAmountA>0) _walletA.transfer(walletAmountA);
uint256 walletAmountB = walletProportion[_walletB].mul(currentFunds).div(100);
if (walletAmountB>0) _walletB.transfer(walletAmountB);
uint256 walletAmountC = walletProportion[_walletC].mul(currentFunds).div(100);
if (walletAmountC>0) _walletC.transfer(walletAmountC);
_weiDistributed.add(currentFunds);
emit FundsDistributed(_walletA, walletAmountA, _walletB, walletAmountB, _walletC, walletAmountC);
}
}
/**
*
* @param _duration round duration in seconds
* @param _cap round cap amount in ETH
* @param _rate round rate in terms of tokens per ETH
* @param _max max eth contribution per addresss
* @param _min min eth contribution per addresss
*/
function addRound(uint256 _duration, uint256 _cap, uint256 _rate, uint256 _max, uint256 _min) public onlyOwner {
Round memory newRound = Round(0,0,_duration,_cap, _rate, _max,_min);
RoundDetails memory genRoundDetails = RoundDetails(0);
rounds.push(newRound);
roundDetails.push(genRoundDetails);
}
function nextStartTime() public view returns(uint256) {
return rounds[currentRound].startTime;
}
function nextStopTime() public view returns(uint256) {
return rounds[currentRound].stopTime;
}
function getFundWallet() public view returns(address,address,address) {
return (_walletA,_walletB, _walletC);
}
function getTriggerAmount() public view returns(uint256) {
return _triggerAmount;
}
function getDistributedAmount() public view returns(uint256) {
return _weiDistributed;
}
function setTriggerAmount(uint256 newTrigger) public onlyOwner {
_triggerAmount=newTrigger;
}
function forceStartNow() public onlyOwner {
---CHUNK-END---
rounds[currentRound].startTime = block.timestamp;
}
function forceStopNow() public onlyOwner {
rounds[currentRound].stopTime = block.timestamp;
}
function updateRound() public {
_updateRound();
}
function withdrawTokens(IERC20 token_, address beneficiary_) public onlyOwner {
uint256 balance = token_.balanceOf(address(this));
require(balance>0, "Crowdsale: no tokens to transfer");
token_.transfer(beneficiary_, balance);
}
function withdrawETH(address payable beneficiary_) public onlyOwner {
uint256 balance = address(this).balance;
require(balance>0, "Crowdsale: no tokens to transfer");
beneficiary_.transfer(balance);
}
}
// File: contracts/access/Roles.sol
pragma solidity ^0.5.0;
/**
* @title Roles
* @dev Library for managing addresses assigned to a Role.
*/
library Roles {
struct Role {
mapping (address => bool) bearer;
}
/**
* @dev Give an account access to this role.
*/
function add(Role storage role, address account) internal {
require(!has(role, account), "Roles: account already has role");
role.bearer[account] = true;
}
/**
* @dev Remove an account's access to this role.
*/
function remove(Role storage role, address account) internal {
require(has(role, account), "Roles: account does not have role");
role.bearer[account] = false;
}
/**
* @dev Check if an account has this role.
* @return bool
*/
function has(Role storage role, address account) internal view returns (bool) {
require(account != address(0), "Roles: account is the zero address");
return role.bearer[account];
}
}
// File: contracts/access/roles/PauserRole.sol
pragma solidity ^0.5.0;
contract PauserRole is Context {
using Roles for Roles.Role;
event PauserAdded(address indexed account);
event PauserRemoved(address indexed account);
Roles.Role private _pausers;
constructor () internal {
_addPauser(_msgSender());
}
modifier onlyPauser() {
require(isPauser(_msgSender()), "PauserRole: caller does not have the Pauser role");
_;
}
function isPauser(address account) public view returns (bool) {
return _pausers.has(account);
}
function addPauser(address account) public onlyPauser {
_addPauser(account);
}
function renouncePauser() public {
_removePauser(_msgSender());
}
function _addPauser(address account) internal {
_pausers.add(account);
emit PauserAdded(account);
}
function _removePauser(address account) internal {
_pausers.remove(account);
emit PauserRemoved(account);
}
}
// File: contracts/lifecycle/Pausable.sol
pragma solidity ^0.5.0;
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
contract Pausable is Context, PauserRole {
/**
* @dev Emitted when the pause is triggered by a pauser (`account`).
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by a pauser (`account`).
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state. Assigns the Pauser role
* to the deployer.
*/
constructor () internal {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*/
modifier whenNotPaused() {
require(!_paused, "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*/
modifier whenPaused() {
require(_paused, "Pausable: not paused");
_;
}
/**
* @dev Called by a pauser to pause, triggers stopped state.
*/
function pause() public onlyPauser whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Called by a pauser to unpause, returns to normal state.
*/
function unpause() public onlyPauser whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
// File: contracts/crowdsale/validation/PausableCrowdsale.sol
pragma solidity ^0.5.0;
/**
* @title PausableCrowdsale
* @dev Extension of Crowdsale contract where purchases can be paused and unpaused by the pauser role.
*/
contract PausableCrowdsale is Crowdsale, Pausable {
/**
* @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met.
* Use super to concatenate validations.
* Adds the validation that the crowdsale must not be paused.
* @param _beneficiary Address performing the token purchase
* @param _weiAmount Value in wei involved in the purchase
*/
function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal view whenNotPaused {
return super._preValidatePurchase(_beneficiary, _weiAmount);
}
}
contract GHCCrowdsale is PausableCrowdsale {
constructor (IERC20 token, address payable walletA, uint256 proportionA, address payable walletB, uint256 proportionB, address payable walletC, uint256 proportionC) Crowdsale(token, walletA, proportionA, walletB, proportionB, walletC, proportionC) public {}
}
exec
/bin/bash -lc "nl -ba contracts/Contract.sol | sed -n '1,420p'" in /tmp/codex-_rc4ifnk
succeeded in 0ms:
1 // File: contracts/GSN/Context.sol
2
3 pragma solidity ^0.5.0;
4
5 /*
6 * @dev Provides information about the current execution context, including the
7 * sender of the transaction and its data. While these are generally available
8 * via msg.sender and msg.data, they should not be accessed in such a direct
9 * manner, since when dealing with GSN meta-transactions the account sending and
10 * paying for execution may not be the actual sender (as far as an application
11 * is concerned).
12 *
13 * This contract is only required for intermediate, library-like contracts.
14 */
15 contract Context {
16 // Empty internal constructor, to prevent people from mistakenly deploying
17 // an instance of this contract, which should be used via inheritance.
18 constructor () internal { }
19 // solhint-disable-previous-line no-empty-blocks
20
21 function _msgSender() internal view returns (address payable) {
22 return msg.sender;
23 }
24
25 function _msgData() internal view returns (bytes memory) {
26 this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
27 return msg.data;
28 }
29 }
30
31 // File: contracts/token/ERC20/IERC20.sol
32
33 pragma solidity ^0.5.0;
34
35 /**
36 * @dev Interface of the ERC20 standard as defined in the EIP. Does not include
37 * the optional functions; to access them see {ERC20Detailed}.
38 */
39 interface IERC20 {
40 /**
41 * @dev Returns the amount of tokens in existence.
42 */
43 function totalSupply() external view returns (uint256);
44
45 /**
46 * @dev Returns the amount of tokens owned by `account`.
47 */
48 function balanceOf(address account) external view returns (uint256);
49
50 /**
51 * @dev Moves `amount` tokens from the caller's account to `recipient`.
52 *
53 * Returns a boolean value indicating whether the operation succeeded.
54 *
55 * Emits a {Transfer} event.
56 */
57 function transfer(address recipient, uint256 amount) external returns (bool);
58
59 /**
60 * @dev Returns the remaining number of tokens that `spender` will be
61 * allowed to spend on behalf of `owner` through {transferFrom}. This is
62 * zero by default.
63 *
64 * This value changes when {approve} or {transferFrom} are called.
65 */
66 function allowance(address owner, address spender) external view returns (uint256);
67
68 /**
69 * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
70 *
71 * Returns a boolean value indicating whether the operation succeeded.
72 *
73 * IMPORTANT: Beware that changing an allowance with this method brings the risk
74 * that someone may use both the old and the new allowance by unfortunate
75 * transaction ordering. One possible solution to mitigate this race
76 * condition is to first reduce the spender's allowance to 0 and set the
77 * desired value afterwards:
78 * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
79 *
80 * Emits an {Approval} event.
81 */
82 function approve(address spender, uint256 amount) external returns (bool);
83
84 /**
85 * @dev Moves `amount` tokens from `sender` to `recipient` using the
86 * allowance mechanism. `amount` is then deducted from the caller's
87 * allowance.
88 *
89 * Returns a boolean value indicating whether the operation succeeded.
90 *
91 * Emits a {Transfer} event.
92 */
93 function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
94
95 /**
96 * @dev Emitted when `value` tokens are moved from one account (`from`) to
97 * another (`to`).
98 *
99 * Note that `value` may be zero.
100 */
101 event Transfer(address indexed from, address indexed to, uint256 value);
102
103 /**
104 * @dev Emitted when the allowance of a `spender` for an `owner` is set by
105 * a call to {approve}. `value` is the new allowance.
106 */
107 event Approval(address indexed owner, address indexed spender, uint256 value);
108 }
109
110 // File: contracts/math/SafeMath.sol
111
112 pragma solidity ^0.5.0;
113
114 /**
115 * @dev Wrappers over Solidity's arithmetic operations with added overflow
116 * checks.
117 *
118 * Arithmetic operations in Solidity wrap on overflow. This can easily result
119 * in bugs, because programmers usually assume that an overflow raises an
120 * error, which is the standard behavior in high level programming languages.
121 * `SafeMath` restores this intuition by reverting the transaction when an
122 * operation overflows.
123 *
124 * Using this library instead of the unchecked operations eliminates an entire
125 * class of bugs, so it's recommended to use it always.
126 */
127 library SafeMath {
128 /**
129 * @dev Returns the addition of two unsigned integers, reverting on
130 * overflow.
131 *
132 * Counterpart to Solidity's `+` operator.
133 *
134 * Requirements:
135 * - Addition cannot overflow.
136 */
137 function add(uint256 a, uint256 b) internal pure returns (uint256) {
138 uint256 c = a + b;
139 require(c >= a, "SafeMath: addition overflow");
140
141 return c;
142 }
143
144 /**
145 * @dev Returns the subtraction of two unsigned integers, reverting on
146 * overflow (when the result is negative).
147 *
148 * Counterpart to Solidity's `-` operator.
149 *
150 * Requirements:
151 * - Subtraction cannot overflow.
152 */
153 function sub(uint256 a, uint256 b) internal pure returns (uint256) {
154 return sub(a, b, "SafeMath: subtraction overflow");
155 }
156
157 /**
158 * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
159 * overflow (when the result is negative).
160 *
161 * Counterpart to Solidity's `-` operator.
162 *
163 * Requirements:
164 * - Subtraction cannot overflow.
165 *
166 * _Available since v2.4.0._
167 */
168 function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
169 require(b <= a, errorMessage);
170 uint256 c = a - b;
171
172 return c;
173 }
174
175 /**
176 * @dev Returns the multiplication of two unsigned integers, reverting on
177 * overflow.
178 *
179 * Counterpart to Solidity's `*` operator.
180 *
181 * Requirements:
182 * - Multiplication cannot overflow.
183 */
184 function mul(uint256 a, uint256 b) internal pure returns (uint256) {
185 // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
186 // benefit is lost if 'b' is also tested.
187 // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
188 if (a == 0) {
189 return 0;
190 }
191
192 uint256 c = a * b;
193 require(c / a == b, "SafeMath: multiplication overflow");
194
195 return c;
196 }
197
198 /**
199 * @dev Returns the integer division of two unsigned integers. Reverts on
200 * division by zero. The result is rounded towards zero.
201 *
202 * Counterpart to Solidity's `/` operator. Note: this function uses a
203 * `revert` opcode (which leaves remaining gas untouched) while Solidity
204 * uses an invalid opcode to revert (consuming all remaining gas).
205 *
206 * Requirements:
207 * - The divisor cannot be zero.
208 */
209 function div(uint256 a, uint256 b) internal pure returns (uint256) {
210 return div(a, b, "SafeMath: division by zero");
211 }
212
213 /**
214 * @dev Returns the integer division of two unsigned integers. Reverts with custom message on
215 * division by zero. The result is rounded towards zero.
216 *
217 * Counterpart to Solidity's `/` operator. Note: this function uses a
218 * `revert` opcode (which leaves remaining gas untouched) while Solidity
219 * uses an invalid opcode to revert (consuming all remaining gas).
220 *
221 * Requirements:
222 * - The divisor cannot be zero.
223 *
224 * _Available since v2.4.0._
225 */
226 function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
227 // Solidity only automatically asserts when dividing by 0
228 require(b > 0, errorMessage);
229 uint256 c = a / b;
230 // assert(a == b * c + a % b); // There is no case in which this doesn't hold
231
232 return c;
233 }
234
235 /**
236 * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
237 * Reverts when dividing by zero.
238 *
239 * Counterpart to Solidity's `%` operator. This function uses a `revert`
240 * opcode (which leaves remaining gas untouched) while Solidity uses an
241 * invalid opcode to revert (consuming all remaining gas).
242 *
243 * Requirements:
244 * - The divisor cannot be zero.
245 */
246 function mod(uint256 a, uint256 b) internal pure returns (uint256) {
247 return mod(a, b, "SafeMath: modulo by zero");
248 }
249
250 /**
251 * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
252 * Reverts with custom message when dividing by zero.
253 *
254 * Counterpart to Solidity's `%` operator. This function uses a `revert`
255 * opcode (which leaves remaining gas untouched) while Solidity uses an
256 * invalid opcode to revert (consuming all remaining gas).
257 *
258 * Requirements:
259 * - The divisor cannot be zero.
260 *
261 * _Available since v2.4.0._
262 */
263 function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
264 require(b != 0, errorMessage);
265 return a % b;
266 }
267 }
268
269 // File: contracts/utils/Address.sol
270
271 pragma solidity ^0.5.5;
272
273 /**
274 * @dev Collection of functions related to the address type
275 */
276 library Address {
277 /**
278 * @dev Returns true if `account` is a contract.
279 *
280 * [IMPORTANT]
281 * ====
282 * It is unsafe to assume that an address for which this function returns
283 * false is an externally-owned account (EOA) and not a contract.
284 *
285 * Among others, `isContract` will return false for the following
286 * types of addresses:
287 *
288 * - an externally-owned account
289 * - a contract in construction
290 * - an address where a contract will be created
291 * - an address where a contract lived, but was destroyed
292 * ====
293 */
294 function isContract(address account) internal view returns (bool) {
295 // According to EIP-1052, 0x0 is the value returned for not-yet created accounts
296 // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
297 // for accounts without code, i.e. `keccak256('')`
298 bytes32 codehash;
299 bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
300 // solhint-disable-next-line no-inline-assembly
301 assembly { codehash := extcodehash(account) }
302 return (codehash != accountHash && codehash != 0x0);
303 }
304
305 /**
306 * @dev Converts an `address` into `address payable`. Note that this is
307 * simply a type cast: the actual underlying value is not changed.
308 *
309 * _Available since v2.4.0._
310 */
311 function toPayable(address account) internal pure returns (address payable) {
312 return address(uint160(account));
313 }
314
315 /**
316 * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
317 * `recipient`, forwarding all available gas and reverting on errors.
318 *
319 * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
320 * of certain opcodes, possibly making contracts go over the 2300 gas limit
321 * imposed by `transfer`, making them unable to receive funds via
322 * `transfer`. {sendValue} removes this limitation.
323 *
324 * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
325 *
326 * IMPORTANT: because control is transferred to `recipient`, care must be
327 * taken to not create reentrancy vulnerabilities. Consider using
328 * {ReentrancyGuard} or the
329 * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
330 *
331 * _Available since v2.4.0._
332 */
333 function sendValue(address payable recipient, uint256 amount) internal {
334 require(address(this).balance >= amount, "Address: insufficient balance");
335
336 // solhint-disable-next-line avoid-call-value
337 (bool success, ) = recipient.call.value(amount)("");
338 require(success, "Address: unable to send value, recipient may have reverted");
339 }
340 }
341
342 // File: contracts/token/ERC20/SafeERC20.sol
343
344 pragma solidity ^0.5.0;
345
346
347
348
349 /**
350 * @title SafeERC20
351 * @dev Wrappers around ERC20 operations that throw on failure (when the token
352 * contract returns false). Tokens that return no value (and instead revert or
353 * throw on failure) are also supported, non-reverting calls are assumed to be
354 * successful.
355 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
356 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
357 */
358 library SafeERC20 {
359 using SafeMath for uint256;
360 using Address for address;
361
362 function safeTransfer(IERC20 token, address to, uint256 value) internal {
363 callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
364 }
365
366 function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
367 callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
368 }
369
370 function safeApprove(IERC20 token, address spender, uint256 value) internal {
371 // safeApprove should only be called when setting an initial allowance,
372 // or when resetting it to zero. To increase and decrease it, use
373 // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
374 // solhint-disable-next-line max-line-length
375 require((value == 0) || (token.allowance(address(this), spender) == 0),
376 "SafeERC20: approve from non-zero to non-zero allowance"
377 );
378 callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
379 }
380
381 function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
382 uint256 newAllowance = token.allowance(address(this), spender).add(value);
383 callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
384 }
385
386 function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
387 uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
388 callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
389 }
390
391 /**
392 * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
393 * on the return value: the return value is optional (but if data is returned, it must not be false).
394 * @param token The token targeted by the call.
395 * @param data The call data (encoded using abi.encode or one of its variants).
396 */
397 function callOptionalReturn(IERC20 token, bytes memory data) private {
398 // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
399 // we're implementing it ourselves.
400
401 // A Solidity high level call has three parts:
402 // 1. The target address is checked to verify it contains contract code
403 // 2. The call itself is made, and success asserted
404 // 3. The return value is decoded, which in turn checks the size of the returned data.
405 // solhint-disable-next-line max-line-length
406 require(address(token).isContract(), "SafeERC20: call to non-contract");
407
408 // solhint-disable-next-line avoid-low-level-calls
409 (bool success, bytes memory returndata) = address(token).call(data);
410 require(success, "SafeERC20: low-level call failed");
411
412 if (returndata.length > 0) { // Return data is optional
413 // solhint-disable-next-line max-line-length
414 require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
415 }
416 }
417 }
418
419
420 // File: contracts/ownership/Ownable.sol
exec
/bin/bash -lc "nl -ba contracts/Contract.sol | sed -n '420,760p'" in /tmp/codex-_rc4ifnk
succeeded in 0ms:
420 // File: contracts/ownership/Ownable.sol
421
422 pragma solidity ^0.5.0;
423
424 /**
425 * @dev Contract module which provides a basic access control mechanism, where
426 * there is an account (an owner) that can be granted exclusive access to
427 * specific functions.
428 *
429 * This module is used through inheritance. It will make available the modifier
430 * `onlyOwner`, which can be applied to your functions to restrict their use to
431 * the owner.
432 */
433 contract Ownable is Context {
434 address private _owner;
435
436 event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
437
438 /**
439 * @dev Initializes the contract setting the deployer as the initial owner.
440 */
441 constructor () internal {
442 address msgSender = _msgSender();
443 _owner = msgSender;
444 emit OwnershipTransferred(address(0), msgSender);
445 }
446
447 /**
448 * @dev Returns the address of the current owner.
449 */
450 function owner() public view returns (address) {
451 return _owner;
452 }
453
454 /**
455 * @dev Throws if called by any account other than the owner.
456 */
457 modifier onlyOwner() {
458 require(isOwner(), "Ownable: caller is not the owner");
459 _;
460 }
461
462 /**
463 * @dev Returns true if the caller is the current owner.
464 */
465 function isOwner() public view returns (bool) {
466 return _msgSender() == _owner;
467 }
468
469 /**
470 * @dev Leaves the contract without owner. It will not be possible to call
471 * `onlyOwner` functions anymore. Can only be called by the current owner.
472 *
473 * NOTE: Renouncing ownership will leave the contract without an owner,
474 * thereby removing any functionality that is only available to the owner.
475 */
476 function renounceOwnership() public onlyOwner {
477 emit OwnershipTransferred(_owner, address(0));
478 _owner = address(0);
479 }
480
481 /**
482 * @dev Transfers ownership of the contract to a new account (`newOwner`).
483 * Can only be called by the current owner.
484 */
485 function transferOwnership(address newOwner) public onlyOwner {
486 _transferOwnership(newOwner);
487 }
488
489 /**
490 * @dev Transfers ownership of the contract to a new account (`newOwner`).
491 */
492 function _transferOwnership(address newOwner) internal {
493 require(newOwner != address(0), "Ownable: new owner is the zero address");
494 emit OwnershipTransferred(_owner, newOwner);
495 _owner = newOwner;
496 }
497 }
498
499
500 // File: contracts/utils/ReentrancyGuard.sol
501
502 pragma solidity ^0.5.0;
503
504 /**
505 * @dev Contract module that helps prevent reentrant calls to a function.
506 *
507 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
508 * available, which can be applied to functions to make sure there are no nested
509 * (reentrant) calls to them.
510 *
511 * Note that because there is a single `nonReentrant` guard, functions marked as
512 * `nonReentrant` may not call one another. This can be worked around by making
513 * those functions `private`, and then adding `external` `nonReentrant` entry
514 * points to them.
515 *
516 * TIP: If you would like to learn more about reentrancy and alternative ways
517 * to protect against it, check out our blog post
518 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
519 *
520 * _Since v2.5.0:_ this module is now much more gas efficient, given net gas
521 * metering changes introduced in the Istanbul hardfork.
522 */
523 contract ReentrancyGuard {
524 bool private _notEntered;
525
526 constructor () internal {
527 // Storing an initial non-zero value makes deployment a bit more
528 // expensive, but in exchange the refund on every call to nonReentrant
529 // will be lower in amount. Since refunds are capped to a percetange of
530 // the total transaction's gas, it is best to keep them low in cases
531 // like this one, to increase the likelihood of the full refund coming
532 // into effect.
533 _notEntered = true;
534 }
535
536 /**
537 * @dev Prevents a contract from calling itself, directly or indirectly.
538 * Calling a `nonReentrant` function from another `nonReentrant`
539 * function is not supported. It is possible to prevent this from happening
540 * by making the `nonReentrant` function external, and make it call a
541 * `private` function that does the actual work.
542 */
543 modifier nonReentrant() {
544 // On the first call to nonReentrant, _notEntered will be true
545 require(_notEntered, "ReentrancyGuard: reentrant call");
546
547 // Any calls to nonReentrant after this point will fail
548 _notEntered = false;
549
550 _;
551
552 // By storing the original value once again, a refund is triggered (see
553 // https://eips.ethereum.org/EIPS/eip-2200)
554 _notEntered = true;
555 }
556 }
557
558 // File: contracts/crowdsale/Crowdsale.sol
559
560 pragma solidity ^0.5.0;
561
562
563
564
565
566
567 /**
568 * @title Crowdsale
569 * @dev Crowdsale is a base contract for managing a token crowdsale,
570 * allowing investors to purchase tokens with ether. This contract implements
571 * such functionality in its most fundamental form and can be extended to provide additional
572 * functionality and/or custom behavior.
573 * The external interface represents the basic interface for purchasing tokens, and conforms
574 * the base architecture for crowdsales. It is *not* intended to be modified / overridden.
575 * The internal interface conforms the extensible and modifiable surface of crowdsales. Override
576 * the methods to add functionality. Consider using 'super' where appropriate to concatenate
577 * behavior.
578 */
579 contract Crowdsale is Context, ReentrancyGuard, Ownable {
580 using SafeMath for uint256;
581 using SafeERC20 for IERC20;
582
583 uint256 private HOUR_TO_SECOND = 3600;
584
585 // GHC Custom Logic
586 struct Round {
587 uint256 startTime;
588 uint256 stopTime;
589 uint256 duration;
590 uint256 roundCap;
591 uint256 rate; // in ETH
592 uint256 maxContibution; // in ETH
593 uint256 minContibution; // in ETH
594 }
595
596 struct RoundDetails {
597 uint256 amountReached;
598 mapping (address => uint256) contributors;
599 }
600
601 event FundsDistributed(address walletA,uint256 amountA, address walletB,uint256 amountB, address walletC, uint256 amountC);
602
603 Round[] public rounds;
604 RoundDetails[] public roundDetails;
605
606 uint256 public currentRound=0;
607
608 // The token being sold
609 IERC20 private _token;
610
611 uint256 private _weiRaised;
612 uint256 private _weiDistributed;
613
614
615 address payable private _walletA;
616 address payable private _walletB;
617 address payable private _walletC;
618
619 // Amount when reached to distribute funds
620 uint256 private _triggerAmount = 20*10**18;
621
622 mapping (address => uint256) public walletProportion;
623
624
625 function _updateRound() internal {
626 uint256 nextRound = currentRound+1;
627 if (rounds[currentRound].stopTime < block.timestamp && rounds.length > nextRound) {
628 // has new round in queue
629 currentRound++;
630 rounds[currentRound].startTime = block.timestamp + HOUR_TO_SECOND*72;
631 rounds[currentRound].stopTime = rounds[currentRound].startTime + rounds[currentRound].duration;
632 // add prev. unused tokens to next pool
633 if (currentRound>1){
634 rounds[currentRound].roundCap = rounds[currentRound].roundCap + rounds[currentRound-1].roundCap - roundDetails[currentRound-1].amountReached;
635 }
636 }
637 else if (rounds[currentRound].stopTime < block.timestamp && rounds.length > currentRound+1 && rounds[currentRound].roundCap <= roundDetails[currentRound].amountReached) {
638 currentRound++;
639 rounds[currentRound].startTime = block.timestamp + HOUR_TO_SECOND*12;
640 rounds[currentRound].stopTime = rounds[currentRound].startTime + rounds[currentRound].duration;
641 }
642 }
643
644 function _checkRoundValidity(address _contributor, uint256 _amount) internal view {
645 require(block.timestamp <= rounds[currentRound].stopTime,"GHCCrowdale: crowdsale stopped");
646 require(block.timestamp >= rounds[currentRound].startTime,"GHCCrowdale: crowdsale not started");
647 require(roundDetails[currentRound].amountReached + _amount <= rounds[currentRound].roundCap, "GHCCrowdale: round amount oveflow");
648 require(roundDetails[currentRound].contributors[_contributor]+_amount <= rounds[currentRound].maxContibution, "GHCCrowdale: max amount reached for round");
649 require(_amount >= rounds[currentRound].minContibution, "GHCCrowdale: max amount reached for round");
650 }
651
652 // // How many token units a buyer gets per wei.
653 // // The rate is the conversion between wei and the smallest and indivisible token unit.
654 // // So, if you are using a rate of 1 with a ERC20Detailed token with 3 decimals called TOK
655 // // 1 wei will give you 1 unit, or 0.001 TOK.
656 // uint256 private _rate;
657
658 // // Amount of wei raised
659 // uint256 private _weiRaised;
660
661 /**
662 * Event for token purchase logging
663 * @param purchaser who paid for the tokens
664 * @param beneficiary who got the tokens
665 * @param value weis paid for purchase
666 * @param amount amount of tokens purchased
667 */
668 event TokensPurchased(address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
669
670 /**
671 * @dev The rate is the conversion between wei and the smallest and indivisible
672 * token unit. So, if you are using a rate of 1 with a ERC20Detailed token
673 * with 3 decimals called TOK, 1 wei will give you 1 unit, or 0.001 TOK.
674 * @param token Address of the token being sold
675 */
676 constructor (IERC20 token, address payable walletA, uint256 proportionA, address payable walletB, uint256 proportionB, address payable walletC, uint256 proportionC) public {
677 require(address(token) != address(0), "Crowdsale: token is the zero address");
678 require(proportionA+proportionB+proportionC==100, "Crowdsale: 100% funds need to be distributed");
679
680 _token = token;
681
682 _walletA=walletA;
683 walletProportion[_walletA]=proportionA;
684 _walletB=walletB;
685 walletProportion[_walletB]=proportionB;
686 _walletC=walletC;
687 walletProportion[_walletC]=proportionC;
688
689 Round memory genRound = Round(0,0,0,0,0,0,0);
690 RoundDetails memory genRoundDetails = RoundDetails(0);
691 rounds.push(genRound);
692 roundDetails.push(genRoundDetails);
693 }
694
695 /**
696 * @dev fallback function ***DO NOT OVERRIDE***
697 * Note that other contracts will transfer funds with a base gas stipend
698 * of 2300, which is not enough to call buyTokens. Consider calling
699 * buyTokens directly when purchasing tokens from a contract.
700 */
701 function () external payable {
702 buyTokens(_msgSender());
703 }
704
705 /**
706 * @return the token being sold.
707 */
708 function token() public view returns (IERC20) {
709 return _token;
710 }
711
712 /**
713 * @return the amount of wei raised.
714 */
715 function weiRaised() public view returns (uint256) {
716 return _weiRaised;
717 }
718
719 /**
720 * @dev low level token purchase ***DO NOT OVERRIDE***
721 * This function has a non-reentrancy guard, so it shouldn't be called by
722 * another `nonReentrant` function.
723 * @param beneficiary Recipient of the token purchase
724 */
725 function buyTokens(address beneficiary) public payable {
726 _updateRound();
727 _checkRoundValidity(msg.sender, msg.value);
728 uint256 weiAmount = msg.value;
729 _preValidatePurchase(beneficiary, weiAmount);
730
731 // calculate token amount to be created // Change token amount from 18 decimal
732 uint256 tokens = _getTokenAmount(weiAmount);
733
734 // update state
735 _weiRaised = _weiRaised.add(weiAmount);
736
737 _processPurchase(beneficiary, tokens);
738 emit TokensPurchased(_msgSender(), beneficiary, weiAmount, tokens);
739
740 _updatePurchasingState(beneficiary, weiAmount);
741
742 _forwardFunds();
743 _postValidatePurchase(beneficiary, weiAmount);
744
745 // update currentRound amountReached
746 roundDetails[currentRound].amountReached = roundDetails[currentRound].amountReached.add(weiAmount);
747
748 }
749
750 /**
751 * @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met.
752 * Use `super` in contracts that inherit from Crowdsale to extend their validations.
753 * Example from CappedCrowdsale.sol's _preValidatePurchase method:
754 * super._preValidatePurchase(beneficiary, weiAmount);
755 * require(weiRaised().add(weiAmount) <= cap);
756 * @param beneficiary Address performing the token purchase
757 * @param weiAmount Value in wei involved in the purchase
758 */
759 function _preValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
760 require(beneficiary != address(0), "Crowdsale: beneficiary is the zero address");
exec
/bin/bash -lc "nl -ba contracts/Contract.sol | sed -n '760,980p'" in /tmp/codex-_rc4ifnk
succeeded in 0ms:
760 require(beneficiary != address(0), "Crowdsale: beneficiary is the zero address");
761 require(weiAmount != 0, "Crowdsale: weiAmount is 0");
762 this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
763 }
764
765 /**
766 * @dev Validation of an executed purchase. Observe state and use revert statements to undo rollback when valid
767 * conditions are not met.
768 * @param beneficiary Address performing the token purchase
769 * @param weiAmount Value in wei involved in the purchase
770 */
771 function _postValidatePurchase(address beneficiary, uint256 weiAmount) internal view {
772 // solhint-disable-previous-line no-empty-blocks
773 }
774
775 /**
776 * @dev Source of tokens. Override this method to modify the way in which the crowdsale ultimately gets and sends
777 * its tokens.
778 * @param beneficiary Address performing the token purchase
779 * @param tokenAmount Number of tokens to be emitted
780 */
781 function _deliverTokens(address beneficiary, uint256 tokenAmount) internal {
782 _token.safeTransfer(beneficiary, tokenAmount);
783 }
784
785 /**
786 * @dev Executed when a purchase has been validated and is ready to be executed. Doesn't necessarily emit/send
787 * tokens.
788 * @param beneficiary Address receiving the tokens
789 * @param tokenAmount Number of tokens to be purchased
790 */
791 function _processPurchase(address beneficiary, uint256 tokenAmount) internal {
792 _deliverTokens(beneficiary, tokenAmount);
793 }
794
795 /**
796 * @dev Override for extensions that require an internal state to check for validity (current user contributions,
797 * etc.)
798 * @param beneficiary Address receiving the tokens
799 * @param weiAmount Value in wei involved in the purchase
800 */
801 function _updatePurchasingState(address beneficiary, uint256 weiAmount) internal {
802 // solhint-disable-previous-line no-empty-blocks
803 }
804
805 /**
806 * @dev Override to extend the way in which ether is converted to tokens.
807 * @param weiAmount Value in wei to be converted into tokens
808 * @return Number of tokens that can be purchased with the specified _weiAmount
809 */
810 function _getTokenAmount(uint256 weiAmount) internal view returns (uint256) {
811 return weiAmount.mul(rounds[currentRound].rate);
812 }
813
814 /**
815 * @dev Determines how ETH is stored/forwarded on purchases.
816 */
817 function _forwardFunds() internal {
818 uint256 currentFunds = _weiRaised.sub(_weiDistributed);
819 if (currentFunds >= _triggerAmount) {
820 uint256 walletAmountA = walletProportion[_walletA].mul(currentFunds).div(100);
821 if (walletAmountA>0) _walletA.transfer(walletAmountA);
822 uint256 walletAmountB = walletProportion[_walletB].mul(currentFunds).div(100);
823 if (walletAmountB>0) _walletB.transfer(walletAmountB);
824 uint256 walletAmountC = walletProportion[_walletC].mul(currentFunds).div(100);
825 if (walletAmountC>0) _walletC.transfer(walletAmountC);
826
827 _weiDistributed.add(currentFunds);
828
829 emit FundsDistributed(_walletA, walletAmountA, _walletB, walletAmountB, _walletC, walletAmountC);
830 }
831
832 }
833
834 /**
835 *
836 * @param _duration round duration in seconds
837 * @param _cap round cap amount in ETH
838 * @param _rate round rate in terms of tokens per ETH
839 * @param _max max eth contribution per addresss
840 * @param _min min eth contribution per addresss
841 */
842 function addRound(uint256 _duration, uint256 _cap, uint256 _rate, uint256 _max, uint256 _min) public onlyOwner {
843 Round memory newRound = Round(0,0,_duration,_cap, _rate, _max,_min);
844 RoundDetails memory genRoundDetails = RoundDetails(0);
845 rounds.push(newRound);
846 roundDetails.push(genRoundDetails);
847 }
848
849
850 function nextStartTime() public view returns(uint256) {
851 return rounds[currentRound].startTime;
852 }
853
854 function nextStopTime() public view returns(uint256) {
855 return rounds[currentRound].stopTime;
856 }
857
858 function getFundWallet() public view returns(address,address,address) {
859 return (_walletA,_walletB, _walletC);
860 }
861
862 function getTriggerAmount() public view returns(uint256) {
863 return _triggerAmount;
864 }
865
866 function getDistributedAmount() public view returns(uint256) {
867 return _weiDistributed;
868 }
869
870 function setTriggerAmount(uint256 newTrigger) public onlyOwner {
871 _triggerAmount=newTrigger;
872 }
873
874 function forceStartNow() public onlyOwner {
875 rounds[currentRound].startTime = block.timestamp;
876 }
877
878 function forceStopNow() public onlyOwner {
879 rounds[currentRound].stopTime = block.timestamp;
880 }
881
882 function updateRound() public {
883 _updateRound();
884 }
885
886 function withdrawTokens(IERC20 token_, address beneficiary_) public onlyOwner {
887 uint256 balance = token_.balanceOf(address(this));
888 require(balance>0, "Crowdsale: no tokens to transfer");
889 token_.transfer(beneficiary_, balance);
890 }
891
892 function withdrawETH(address payable beneficiary_) public onlyOwner {
893 uint256 balance = address(this).balance;
894 require(balance>0, "Crowdsale: no tokens to transfer");
895 beneficiary_.transfer(balance);
896 }
897 }
898
899 // File: contracts/access/Roles.sol
900
901 pragma solidity ^0.5.0;
902
903 /**
904 * @title Roles
905 * @dev Library for managing addresses assigned to a Role.
906 */
907 library Roles {
908 struct Role {
909 mapping (address => bool) bearer;
910 }
911
912 /**
913 * @dev Give an account access to this role.
914 */
915 function add(Role storage role, address account) internal {
916 require(!has(role, account), "Roles: account already has role");
917 role.bearer[account] = true;
918 }
919
920 /**
921 * @dev Remove an account's access to this role.
922 */
923 function remove(Role storage role, address account) internal {
924 require(has(role, account), "Roles: account does not have role");
925 role.bearer[account] = false;
926 }
927
928 /**
929 * @dev Check if an account has this role.
930 * @return bool
931 */
932 function has(Role storage role, address account) internal view returns (bool) {
933 require(account != address(0), "Roles: account is the zero address");
934 return role.bearer[account];
935 }
936 }
937
938 // File: contracts/access/roles/PauserRole.sol
939
940 pragma solidity ^0.5.0;
941
942
943
944 contract PauserRole is Context {
945 using Roles for Roles.Role;
946
947 event PauserAdded(address indexed account);
948 event PauserRemoved(address indexed account);
949
950 Roles.Role private _pausers;
951
952 constructor () internal {
953 _addPauser(_msgSender());
954 }
955
956 modifier onlyPauser() {
957 require(isPauser(_msgSender()), "PauserRole: caller does not have the Pauser role");
958 _;
959 }
960
961 function isPauser(address account) public view returns (bool) {
962 return _pausers.has(account);
963 }
964
965 function addPauser(address account) public onlyPauser {
966 _addPauser(account);
967 }
968
969 function renouncePauser() public {
970 _removePauser(_msgSender());
971 }
972
973 function _addPauser(address account) internal {
974 _pausers.add(account);
975 emit PauserAdded(account);
976 }
977
978 function _removePauser(address account) internal {
979 _pausers.remove(account);
980 emit PauserRemoved(account);
exec
/bin/bash -lc "nl -ba contracts/Contract.sol | sed -n '980,1080p'" in /tmp/codex-_rc4ifnk
succeeded in 0ms:
980 emit PauserRemoved(account);
981 }
982 }
983
984 // File: contracts/lifecycle/Pausable.sol
985
986 pragma solidity ^0.5.0;
987
988
989
990 /**
991 * @dev Contract module which allows children to implement an emergency stop
992 * mechanism that can be triggered by an authorized account.
993 *
994 * This module is used through inheritance. It will make available the
995 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
996 * the functions of your contract. Note that they will not be pausable by
997 * simply including this module, only once the modifiers are put in place.
998 */
999 contract Pausable is Context, PauserRole {
1000 /**
1001 * @dev Emitted when the pause is triggered by a pauser (`account`).
1002 */
1003 event Paused(address account);
1004
1005 /**
1006 * @dev Emitted when the pause is lifted by a pauser (`account`).
1007 */
1008 event Unpaused(address account);
1009
1010 bool private _paused;
1011
1012 /**
1013 * @dev Initializes the contract in unpaused state. Assigns the Pauser role
1014 * to the deployer.
1015 */
1016 constructor () internal {
1017 _paused = false;
1018 }
1019
1020 /**
1021 * @dev Returns true if the contract is paused, and false otherwise.
1022 */
1023 function paused() public view returns (bool) {
1024 return _paused;
1025 }
1026
1027 /**
1028 * @dev Modifier to make a function callable only when the contract is not paused.
1029 */
1030 modifier whenNotPaused() {
1031 require(!_paused, "Pausable: paused");
1032 _;
1033 }
1034
1035 /**
1036 * @dev Modifier to make a function callable only when the contract is paused.
1037 */
1038 modifier whenPaused() {
1039 require(_paused, "Pausable: not paused");
1040 _;
1041 }
1042
1043 /**
1044 * @dev Called by a pauser to pause, triggers stopped state.
1045 */
1046 function pause() public onlyPauser whenNotPaused {
1047 _paused = true;
1048 emit Paused(_msgSender());
1049 }
1050
1051 /**
1052 * @dev Called by a pauser to unpause, returns to normal state.
1053 */
1054 function unpause() public onlyPauser whenPaused {
1055 _paused = false;
1056 emit Unpaused(_msgSender());
1057 }
1058 }
1059
1060 // File: contracts/crowdsale/validation/PausableCrowdsale.sol
1061
1062 pragma solidity ^0.5.0;
1063
1064
1065
1066 /**
1067 * @title PausableCrowdsale
1068 * @dev Extension of Crowdsale contract where purchases can be paused and unpaused by the pauser role.
1069 */
1070 contract PausableCrowdsale is Crowdsale, Pausable {
1071 /**
1072 * @dev Validation of an incoming purchase. Use require statements to revert state when conditions are not met.
1073 * Use super to concatenate validations.
1074 * Adds the validation that the crowdsale must not be paused.
1075 * @param _beneficiary Address performing the token purchase
1076 * @param _weiAmount Value in wei involved in the purchase
1077 */
1078 function _preValidatePurchase(address _beneficiary, uint256 _weiAmount) internal view whenNotPaused {
1079 return super._preValidatePurchase(_beneficiary, _weiAmount);
1080 }
I finished reading the full audit bundle and traced the crowdsale state transitions. The material issues are concentrated in the custom sale/accounting logic around purchases and fund distribution.
✓ Read AUDIT_BUNDLE.txt completely
✓ Analyze first-party contract logic for exploitable issues
→ Produce JSON findings with evidence and locations
codex
{"no_findings":false,"summary":"The first-party crowdsale logic has broken ETH distribution accounting, broken per-address contribution accounting, and a reentrancy-prone purchase flow that updates round state after external token delivery.","findings":[{"severity":"high","category":"other","title":"ETH distribution accounting is never persisted, so crossing the payout threshold can brick subsequent purchases","exploit_scenario":"Once total raised ETH reaches `_triggerAmount`, `_forwardFunds()` distributes the full `currentFunds` balance to the three wallets. Because `_weiDistributed` is not assigned back, it stays `0`. On the next purchase, `currentFunds` is recalculated as the cumulative `_weiRaised`, not the undistributed amount, so the function attempts to pay out more ETH than the contract actually holds and the purchase reverts. Any buyer can be the one who pushes the sale over the threshold and trigger this broken state.","recommendation":"Persist the distribution state with `_weiDistributed = _weiDistributed.add(currentFunds);` before returning, and add tests that cover multiple payout cycles after several purchases.","evidence":"`currentFunds` is derived from `_weiRaised.sub(_weiDistributed)`, but line 827 calls `_weiDistributed.add(currentFunds);` without storing the result. The contract therefore forgets every prior distribution.","locations":["contracts/Contract.sol:818","contracts/Contract.sol:821","contracts/Contract.sol:823","contracts/Contract.sol:825","contracts/Contract.sol:827"]},{"severity":"medium","category":"other","title":"Per-address round contribution caps are unenforced because contributor totals are never updated","exploit_scenario":"A buyer can split a large purchase into many transactions and exceed the advertised `maxContibution` for the round. `_checkRoundValidity()` checks `roundDetails[currentRound].contributors[_contributor] + _amount`, but that mapping is never incremented anywhere in the purchase flow, so each call is validated as if the sender had contributed `0` previously.","recommendation":"Update `roundDetails[currentRound].contributors[beneficiary or msg.sender]` during the purchase flow before external interactions, and add tests that assert cumulative per-round limits across multiple transactions.","evidence":"The limit check reads `contributors[_contributor]` at line 648, but `_updatePurchasingState()` is empty and no other code writes to the `contributors` mapping.","locations":["contracts/Contract.sol:648","contracts/Contract.sol:740","contracts/Contract.sol:801"]},{"severity":"medium","category":"reentrancy","title":"buyTokens performs external token delivery before round accounting and lacks the advertised reentrancy guard","exploit_scenario":"If the sale token is ERC777-like or otherwise invokes a callback during `transfer`, a contract beneficiary can reenter `buyTokens` from that callback with additional ETH. Because `roundDetails[currentRound].amountReached` and the contributor mapping are only updated after `_deliverTokens`, the nested call sees stale round state and can bypass round-cap and per-address-limit checks within the same transaction.","recommendation":"Mark `buyTokens` as `nonReentrant` and move round accounting updates ahead of `_processPurchase()` so all cap checks observe committed state before any external call.","evidence":"The function comment says `buyTokens` has a non-reentrancy guard, but no `nonReentrant` modifier is present. `_processPurchase()` calls `_token.safeTransfer(...)` before `amountReached` is incremented at line 746.","locations":["contracts/Contract.sol:721","contracts/Contract.sol:725","contracts/Contract.sol:737","contracts/Contract.sol:746","contracts/Contract.sol:781"]}]}
tokens used
54,517
{
"codex": {
"ran_at": "2026-04-04T02:58:43.862764+00:00",
"returncode": 0
},
"project": {
"mode": "source",
"file_count": 1,
"import_count": 0,
"first_party_contracts_count": 1
},
"summary": "The first-party crowdsale logic has broken ETH distribution accounting, broken per-address contribution accounting, and a reentrancy-prone purchase flow that updates round state after external token delivery.",
"raw_final": {
"summary": "The first-party crowdsale logic has broken ETH distribution accounting, broken per-address contribution accounting, and a reentrancy-prone purchase flow that updates round state after external token delivery.",
"findings": [
{
"title": "ETH distribution accounting is never persisted, so crossing the payout threshold can brick subsequent purchases",
"category": "other",
"evidence": "`currentFunds` is derived from `_weiRaised.sub(_weiDistributed)`, but line 827 calls `_weiDistributed.add(currentFunds);` without storing the result. The contract therefore forgets every prior distribution.",
"severity": "high",
"locations": [
"contracts/Contract.sol:818",
"contracts/Contract.sol:821",
"contracts/Contract.sol:823",
"contracts/Contract.sol:825",
"contracts/Contract.sol:827"
],
"recommendation": "Persist the distribution state with `_weiDistributed = _weiDistributed.add(currentFunds);` before returning, and add tests that cover multiple payout cycles after several purchases.",
"exploit_scenario": "Once total raised ETH reaches `_triggerAmount`, `_forwardFunds()` distributes the full `currentFunds` balance to the three wallets. Because `_weiDistributed` is not assigned back, it stays `0`. On the next purchase, `currentFunds` is recalculated as the cumulative `_weiRaised`, not the undistributed amount, so the function attempts to pay out more ETH than the contract actually holds and the purchase reverts. Any buyer can be the one who pushes the sale over the threshold and trigger this broken state."
},
{
"title": "Per-address round contribution caps are unenforced because contributor totals are never updated",
"category": "other",
"evidence": "The limit check reads `contributors[_contributor]` at line 648, but `_updatePurchasingState()` is empty and no other code writes to the `contributors` mapping.",
"severity": "medium",
"locations": [
"contracts/Contract.sol:648",
"contracts/Contract.sol:740",
"contracts/Contract.sol:801"
],
"recommendation": "Update `roundDetails[currentRound].contributors[beneficiary or msg.sender]` during the purchase flow before external interactions, and add tests that assert cumulative per-round limits across multiple transactions.",
"exploit_scenario": "A buyer can split a large purchase into many transactions and exceed the advertised `maxContibution` for the round. `_checkRoundValidity()` checks `roundDetails[currentRound].contributors[_contributor] + _amount`, but that mapping is never incremented anywhere in the purchase flow, so each call is validated as if the sender had contributed `0` previously."
},
{
"title": "buyTokens performs external token delivery before round accounting and lacks the advertised reentrancy guard",
"category": "reentrancy",
"evidence": "The function comment says `buyTokens` has a non-reentrancy guard, but no `nonReentrant` modifier is present. `_processPurchase()` calls `_token.safeTransfer(...)` before `amountReached` is incremented at line 746.",
"severity": "medium",
"locations": [
"contracts/Contract.sol:721",
"contracts/Contract.sol:725",
"contracts/Contract.sol:737",
"contracts/Contract.sol:746",
"contracts/Contract.sol:781"
],
"recommendation": "Mark `buyTokens` as `nonReentrant` and move round accounting updates ahead of `_processPurchase()` so all cap checks observe committed state before any external call.",
"exploit_scenario": "If the sale token is ERC777-like or otherwise invokes a callback during `transfer`, a contract beneficiary can reenter `buyTokens` from that callback with additional ETH. Because `roundDetails[currentRound].amountReached` and the contributor mapping are only updated after `_deliverTokens`, the nested call sees stale round state and can bypass round-cap and per-address-limit checks within the same transaction."
}
],
"no_findings": false
},
"no_findings": false,
"schema_version": 1
}
00000000: PUSH1 0x80 00000002: PUSH1 0x40 00000004: MSTORE 00000005: PUSH1 0x04 00000007: CALLDATASIZE 00000008: LT 00000009: PUSH2 0x01c2 0000000c: JUMPI 0000000d: PUSH1 0x00 0000000f: CALLDATALOAD 00000010: PUSH1 0xe0 00000012: SHR 00000013: DUP1 00000014: PUSH4 0x8bbf9b07 00000019: GT 0000001a: PUSH2 0x00f7 0000001d: JUMPI 0000001e: DUP1 0000001f: PUSH4 0xabcb4223 00000024: GT 00000025: PUSH2 0x0095 00000028: JUMPI 00000029: DUP1 0000002a: PUSH4 0xeadf6258 0000002f: GT 00000030: PUSH2 0x0064 00000033: JUMPI 00000034: DUP1 00000035: PUSH4 0xeadf6258 0000003a: EQ 0000003b: PUSH2 0x0590 0000003e: JUMPI 0000003f: DUP1 00000040: PUSH4 0xec8ac4d8 00000045: EQ 00000046: PUSH2 0x05a5 00000049: JUMPI 0000004a: DUP1 0000004b: PUSH4 0xf2fde38b 00000050: EQ 00000051: PUSH2 0x05cb 00000054: JUMPI 00000055: DUP1 00000056: PUSH4 0xfc0c546a 0000005b: EQ 0000005c: PUSH2 0x05fe 0000005f: JUMPI 00000060: PUSH2 0x01c2 00000063: JUMP 00000064: JUMPDEST 00000065: DUP1 00000066: PUSH4 0xabcb4223 0000006b: EQ 0000006c: PUSH2 0x0512 0000006f: JUMPI 00000070: DUP1 00000071: PUSH4 0xba166a39 00000076: EQ 00000077: PUSH2 0x0527 0000007a: JUMPI 0000007b: DUP1 0000007c: PUSH4 0xc4af19ce 00000081: EQ 00000082: PUSH2 0x0551 00000085: JUMPI 00000086: DUP1 00000087: PUSH4 0xe4b65f5b 0000008c: EQ 0000008d: PUSH2 0x0566 00000090: JUMPI 00000091: PUSH2 0x01c2 00000094: JUMP 00000095: JUMPDEST 00000096: DUP1 00000097: PUSH4 0x8f32d59b 0000009c: GT 0000009d: PUSH2 0x00d1 000000a0: JUMPI 000000a1: DUP1 000000a2: PUSH4 0x8f32d59b 000000a7: EQ 000000a8: PUSH2 0x046d 000000ab: JUMPI 000000ac: DUP1 000000ad: PUSH4 0x8f95623e 000000b2: EQ 000000b3: PUSH2 0x0482 000000b6: JUMPI 000000b7: DUP1 000000b8: PUSH4 0x9144b615 000000bd: EQ 000000be: PUSH2 0x0497 000000c1: JUMPI 000000c2: DUP1 000000c3: PUSH4 0xa522ad25 000000c8: EQ 000000c9: PUSH2 0x04d7 000000cc: JUMPI 000000cd: PUSH2 0x01c2 000000d0: JUMP 000000d1: JUMPDEST 000000d2: DUP1 000000d3: PUSH4 0x8bbf9b07 000000d8: EQ 000000d9: PUSH2 0x0398 000000dc: JUMPI 000000dd: DUP1 000000de: PUSH4 0x8c65c81f 000000e3: EQ 000000e4: PUSH2 0x03da 000000e7: JUMPI 000000e8: DUP1 000000e9: PUSH4 0x8da5cb5b 000000ee: EQ 000000ef: PUSH2 0x043c 000000f2: JUMPI 000000f3: PUSH2 0x01c2 000000f6: JUMP 000000f7: JUMPDEST 000000f8: DUP1 000000f9: PUSH4 0x690d8320 000000fe: GT 000000ff: PUSH2 0x0164 00000102: JUMPI 00000103: DUP1 00000104: PUSH4 0x7e6a0e39 00000109: GT 0000010a: PUSH2 0x013e 0000010d: JUMPI 0000010e: DUP1 0000010f: PUSH4 0x7e6a0e39 00000114: EQ 00000115: PUSH2 0x0308 00000118: JUMPI 00000119: DUP1 0000011a: PUSH4 0x82dc1ec4 0000011f: EQ 00000120: PUSH2 0x033b 00000123: JUMPI 00000124: DUP1 00000125: PUSH4 0x8456cb59 0000012a: EQ 0000012b: PUSH2 0x036e 0000012e: JUMPI 0000012f: DUP1 00000130: PUSH4 0x8a19c8bc 00000135: EQ 00000136: PUSH2 0x0383 00000139: JUMPI 0000013a: PUSH2 0x01c2 0000013d: JUMP 0000013e: JUMPDEST 0000013f: DUP1 00000140: PUSH4 0x690d8320 00000145: EQ 00000146: PUSH2 0x02ab 00000149: JUMPI 0000014a: DUP1 0000014b: PUSH4 0x6ef8d66d 00000150: EQ 00000151: PUSH2 0x02de 00000154: JUMPI 00000155: DUP1 00000156: PUSH4 0x715018a6 0000015b: EQ 0000015c: PUSH2 0x02f3 0000015f: JUMPI 00000160: PUSH2 0x01c2 00000163: JUMP 00000164: JUMPDEST 00000165: DUP1 00000166: PUSH4 0x4be05f47 0000016b: GT 0000016c: PUSH2 0x01a0 0000016f: JUMPI 00000170: DUP1 00000171: PUSH4 0x4be05f47 00000176: EQ 00000177: PUSH2 0x0257 0000017a: JUMPI 0000017b: DUP1 0000017c: PUSH4 0x559ab6aa 00000181: EQ 00000182: PUSH2 0x026c 00000185: JUMPI 00000186: DUP1 00000187: PUSH4 0x5c975abb 0000018c: EQ 0000018d: PUSH2 0x0281 00000190: JUMPI 00000191: DUP1 00000192: PUSH4 0x6814be87 00000197: EQ 00000198: PUSH2 0x0296 0000019b: JUMPI 0000019c: PUSH2 0x01c2 0000019f: JUMP 000001a0: JUMPDEST 000001a1: DUP1 000001a2: PUSH4 0x3f4ba83a 000001a7: EQ 000001a8: PUSH2 0x01d4 000001ab: JUMPI 000001ac: DUP1 000001ad: PUSH4 0x4042b66f 000001b2: EQ 000001b3: PUSH2 0x01e9 000001b6: JUMPI 000001b7: DUP1 000001b8: PUSH4 0x46fbf68e 000001bd: EQ 000001be: PUSH2 0x0210 000001c1: JUMPI 000001c2: JUMPDEST 000001c3: PUSH2 0x01d2 000001c6: PUSH2 0x01cd 000001c9: PUSH2 0x0613 000001cc: JUMP 000001cd: JUMPDEST 000001ce: PUSH2 0x0617 000001d1: JUMP 000001d2: JUMPDEST 000001d3: STOP 000001d4: JUMPDEST 000001d5: CALLVALUE 000001d6: DUP1 000001d7: ISZERO 000001d8: PUSH2 0x01e0 000001db: JUMPI 000001dc: PUSH1 0x00 000001de: DUP1 000001df: REVERT 000001e0: JUMPDEST 000001e1: POP 000001e2: PUSH2 0x01d2 000001e5: PUSH2 0x072d 000001e8: JUMP 000001e9: JUMPDEST 000001ea: CALLVALUE 000001eb: DUP1 000001ec: ISZERO 000001ed: PUSH2 0x01f5 000001f0: JUMPI 000001f1: PUSH1 0x00 000001f3: DUP1 000001f4: REVERT 000001f5: JUMPDEST 000001f6: POP 000001f7: PUSH2 0x01fe 000001fa: PUSH2 0x0825 000001fd: JUMP 000001fe: JUMPDEST 000001ff: PUSH1 0x40 00000201: DUP1 00000202: MLOAD 00000203: SWAP2 00000204: DUP3 00000205: MSTORE 00000206: MLOAD 00000207: SWAP1 00000208: DUP2 00000209: SWAP1 0000020a: SUB 0000020b: PUSH1 0x20 0000020d: ADD 0000020e: SWAP1 0000020f: RETURN 00000210: JUMPDEST 00000211: CALLVALUE 00000212: DUP1 00000213: ISZERO 00000214: PUSH2 0x021c 00000217: JUMPI 00000218: PUSH1 0x00 0000021a: DUP1 0000021b: REVERT 0000021c: JUMPDEST 0000021d: POP 0000021e: PUSH2 0x0243 00000221: PUSH1 0x04 00000223: DUP1 00000224: CALLDATASIZE 00000225: SUB 00000226: PUSH1 0x20 00000228: DUP2 00000229: LT 0000022a: ISZERO 0000022b: PUSH2 0x0233 0000022e: JUMPI 0000022f: PUSH1 0x00 00000231: DUP1 00000232: REVERT 00000233: JUMPDEST 00000234: POP 00000235: CALLDATALOAD 00000236: PUSH1 0x01 00000238: PUSH1 0x01 0000023a: PUSH1 0xa0 0000023c: SHL 0000023d: SUB 0000023e: AND 0000023f: PUSH2 0x082b 00000242: JUMP 00000243: JUMPDEST 00000244: PUSH1 0x40 00000246: DUP1 00000247: MLOAD 00000248: SWAP2 00000249: ISZERO 0000024a: ISZERO 0000024b: DUP3 0000024c: MSTORE 0000024d: MLOAD 0000024e: SWAP1 0000024f: DUP2 00000250: SWAP1 00000251: SUB 00000252: PUSH1 0x20 00000254: ADD 00000255: SWAP1 00000256: RETURN 00000257: JUMPDEST 00000258: CALLVALUE 00000259: DUP1 0000025a: ISZERO 0000025b: PUSH2 0x0263 0000025e: JUMPI 0000025f: PUSH1 0x00 00000261: DUP1 00000262: REVERT 00000263: JUMPDEST 00000264: POP 00000265: PUSH2 0x01fe 00000268: PUSH2 0x0844 0000026b: JUMP 0000026c: JUMPDEST 0000026d: CALLVALUE 0000026e: DUP1 0000026f: ISZERO 00000270: PUSH2 0x0278 00000273: JUMPI 00000274: PUSH1 0x00 00000276: DUP1 00000277: REVERT 00000278: JUMPDEST 00000279: POP 0000027a: PUSH2 0x01fe 0000027d: PUSH2 0x084a 00000280: JUMP 00000281: JUMPDEST 00000282: CALLVALUE 00000283: DUP1 00000284: ISZERO 00000285: PUSH2 0x028d 00000288: JUMPI 00000289: PUSH1 0x00 0000028b: DUP1 0000028c: REVERT 0000028d: JUMPDEST 0000028e: POP 0000028f: PUSH2 0x0243 00000292: PUSH2 0x0872 00000295: JUMP 00000296: JUMPDEST 00000297: CALLVALUE 00000298: DUP1 00000299: ISZERO 0000029a: PUSH2 0x02a2 0000029d: JUMPI 0000029e: PUSH1 0x00 000002a0: DUP1 000002a1: REVERT 000002a2: JUMPDEST 000002a3: POP 000002a4: PUSH2 0x01fe 000002a7: PUSH2 0x087b 000002aa: JUMP 000002ab: JUMPDEST 000002ac: CALLVALUE 000002ad: DUP1 000002ae: ISZERO 000002af: PUSH2 0x02b7 000002b2: JUMPI 000002b3: PUSH1 0x00 000002b5: DUP1 000002b6: REVERT 000002b7: JUMPDEST 000002b8: POP 000002b9: PUSH2 0x01d2 000002bc: PUSH1 0x04 000002be: DUP1 000002bf: CALLDATASIZE 000002c0: SUB 000002c1: PUSH1 0x20 000002c3: DUP2 000002c4: LT 000002c5: ISZERO 000002c6: PUSH2 0x02ce 000002c9: JUMPI 000002ca: PUSH1 0x00 000002cc: DUP1 000002cd: REVERT 000002ce: JUMPDEST 000002cf: POP 000002d0: CALLDATALOAD 000002d1: PUSH1 0x01 000002d3: PUSH1 0x01 000002d5: PUSH1 0xa0 000002d7: SHL 000002d8: SUB 000002d9: AND 000002da: PUSH2 0x08a3 000002dd: JUMP 000002de: JUMPDEST 000002df: CALLVALUE 000002e0: DUP1 000002e1: ISZERO 000002e2: PUSH2 0x02ea 000002e5: JUMPI 000002e6: PUSH1 0x00 000002e8: DUP1 000002e9: REVERT 000002ea: JUMPDEST 000002eb: POP 000002ec: PUSH2 0x01d2 000002ef: PUSH2 0x097f 000002f2: JUMP 000002f3: JUMPDEST 000002f4: CALLVALUE 000002f5: DUP1 000002f6: ISZERO 000002f7: PUSH2 0x02ff 000002fa: JUMPI 000002fb: PUSH1 0x00 000002fd: DUP1 000002fe: REVERT 000002ff: JUMPDEST 00000300: POP 00000301: PUSH2 0x01d2 00000304: PUSH2 0x0991 00000307: JUMP 00000308: JUMPDEST 00000309: CALLVALUE 0000030a: DUP1 0000030b: ISZERO 0000030c: PUSH2 0x0314 0000030f: JUMPI 00000310: PUSH1 0x00 00000312: DUP1 00000313: REVERT 00000314: JUMPDEST 00000315: POP 00000316: PUSH2 0x01fe 00000319: PUSH1 0x04 0000031b: DUP1 0000031c: CALLDATASIZE 0000031d: SUB 0000031e: PUSH1 0x20 00000320: DUP2 00000321: LT 00000322: ISZERO 00000323: PUSH2 0x032b 00000326: JUMPI 00000327: PUSH1 0x00 00000329: DUP1 0000032a: REVERT 0000032b: JUMPDEST 0000032c: POP 0000032d: CALLDATALOAD 0000032e: PUSH1 0x01 00000330: PUSH1 0x01 00000332: PUSH1 0xa0 00000334: SHL 00000335: SUB 00000336: AND 00000337: PUSH2 0x0a2a 0000033a: JUMP 0000033b: JUMPDEST 0000033c: CALLVALUE 0000033d: DUP1 0000033e: ISZERO 0000033f: PUSH2 0x0347 00000342: JUMPI 00000343: PUSH1 0x00 00000345: DUP1 00000346: REVERT 00000347: JUMPDEST 00000348: POP 00000349: PUSH2 0x01d2 0000034c: PUSH1 0x04 0000034e: DUP1 0000034f: CALLDATASIZE 00000350: SUB 00000351: PUSH1 0x20 00000353: DUP2 00000354: LT 00000355: ISZERO 00000356: PUSH2 0x035e 00000359: JUMPI 0000035a: PUSH1 0x00 0000035c: DUP1 0000035d: REVERT 0000035e: JUMPDEST 0000035f: POP 00000360: CALLDATALOAD 00000361: PUSH1 0x01 00000363: PUSH1 0x01 00000365: PUSH1 0xa0 00000367: SHL 00000368: SUB 00000369: AND 0000036a: PUSH2 0x0a3c 0000036d: JUMP 0000036e: JUMPDEST 0000036f: CALLVALUE 00000370: DUP1 00000371: ISZERO 00000372: PUSH2 0x037a 00000375: JUMPI 00000376: PUSH1 0x00 00000378: DUP1 00000379: REVERT 0000037a: JUMPDEST 0000037b: POP 0000037c: PUSH2 0x01d2 0000037f: PUSH2 0x0a91 00000382: JUMP 00000383: JUMPDEST 00000384: CALLVALUE 00000385: DUP1 00000386: ISZERO 00000387: PUSH2 0x038f 0000038a: JUMPI 0000038b: PUSH1 0x00 0000038d: DUP1 0000038e: REVERT 0000038f: JUMPDEST 00000390: POP 00000391: PUSH2 0x01fe 00000394: PUSH2 0x0b61 00000397: JUMP 00000398: JUMPDEST 00000399: CALLVALUE 0000039a: DUP1 0000039b: ISZERO 0000039c: PUSH2 0x03a4 0000039f: JUMPI 000003a0: PUSH1 0x00 000003a2: DUP1 000003a3: REVERT 000003a4: JUMPDEST 000003a5: POP 000003a6: PUSH2 0x01d2 000003a9: PUSH1 0x04 000003ab: DUP1 000003ac: CALLDATASIZE 000003ad: SUB 000003ae: PUSH1 0xa0 000003b0: DUP2 000003b1: LT 000003b2: ISZERO 000003b3: PUSH2 0x03bb 000003b6: JUMPI 000003b7: PUSH1 0x00 000003b9: DUP1 000003ba: REVERT 000003bb: JUMPDEST 000003bc: POP 000003bd: DUP1 000003be: CALLDATALOAD 000003bf: SWAP1 000003c0: PUSH1 0x20 000003c2: DUP2 000003c3: ADD 000003c4: CALLDATALOAD 000003c5: SWAP1 000003c6: PUSH1 0x40 000003c8: DUP2 000003c9: ADD 000003ca: CALLDATALOAD 000003cb: SWAP1 000003cc: PUSH1 0x60 000003ce: DUP2 000003cf: ADD 000003d0: CALLDATALOAD 000003d1: SWAP1 000003d2: PUSH1 0x80 000003d4: ADD 000003d5: CALLDATALOAD 000003d6: PUSH2 0x0b67 000003d9: JUMP 000003da: JUMPDEST 000003db: CALLVALUE 000003dc: DUP1 000003dd: ISZERO 000003de: PUSH2 0x03e6 000003e1: JUMPI 000003e2: PUSH1 0x00 000003e4: DUP1 000003e5: REVERT 000003e6: JUMPDEST 000003e7: POP 000003e8: PUSH2 0x0404 000003eb: PUSH1 0x04 000003ed: DUP1 000003ee: CALLDATASIZE 000003ef: SUB 000003f0: PUSH1 0x20 000003f2: DUP2 000003f3: LT 000003f4: ISZERO 000003f5: PUSH2 0x03fd 000003f8: JUMPI 000003f9: PUSH1 0x00 000003fb: DUP1 000003fc: REVERT 000003fd: JUMPDEST 000003fe: POP 000003ff: CALLDATALOAD 00000400: PUSH2 0x0d77 00000403: JUMP 00000404: JUMPDEST 00000405: PUSH1 0x40 00000407: DUP1 00000408: MLOAD 00000409: SWAP8 0000040a: DUP9 0000040b: MSTORE 0000040c: PUSH1 0x20 0000040e: DUP9 0000040f: ADD 00000410: SWAP7 00000411: SWAP1 00000412: SWAP7 00000413: MSTORE 00000414: DUP7 00000415: DUP7 00000416: ADD 00000417: SWAP5 00000418: SWAP1 00000419: SWAP5 0000041a: MSTORE 0000041b: PUSH1 0x60 0000041d: DUP7 0000041e: ADD 0000041f: SWAP3 00000420: SWAP1 00000421: SWAP3 00000422: MSTORE 00000423: PUSH1 0x80 00000425: DUP6 00000426: ADD 00000427: MSTORE 00000428: PUSH1 0xa0 0000042a: DUP5 0000042b: ADD 0000042c: MSTORE 0000042d: PUSH1 0xc0 0000042f: DUP4 00000430: ADD 00000431: MSTORE 00000432: MLOAD 00000433: SWAP1 00000434: DUP2 00000435: SWAP1 00000436: SUB 00000437: PUSH1 0xe0 00000439: ADD 0000043a: SWAP1 0000043b: RETURN 0000043c: JUMPDEST 0000043d: CALLVALUE 0000043e: DUP1 0000043f: ISZERO 00000440: PUSH2 0x0448 00000443: JUMPI 00000444: PUSH1 0x00 00000446: DUP1 00000447: REVERT 00000448: JUMPDEST 00000449: POP 0000044a: PUSH2 0x0451 0000044d: PUSH2 0x0dc6 00000450: JUMP 00000451: JUMPDEST 00000452: PUSH1 0x40 00000454: DUP1 00000455: MLOAD 00000456: PUSH1 0x01 00000458: PUSH1 0x01 0000045a: PUSH1 0xa0 0000045c: SHL 0000045d: SUB 0000045e: SWAP1 0000045f: SWAP3 00000460: AND 00000461: DUP3 00000462: MSTORE 00000463: MLOAD 00000464: SWAP1 00000465: DUP2 00000466: SWAP1 00000467: SUB 00000468: PUSH1 0x20 0000046a: ADD 0000046b: SWAP1 0000046c: RETURN 0000046d: JUMPDEST 0000046e: CALLVALUE 0000046f: DUP1 00000470: ISZERO 00000471: PUSH2 0x0479 00000474: JUMPI 00000475: PUSH1 0x00 00000477: DUP1 00000478: REVERT 00000479: JUMPDEST 0000047a: POP 0000047b: PUSH2 0x0243 0000047e: PUSH2 0x0dda 00000481: JUMP 00000482: JUMPDEST 00000483: CALLVALUE 00000484: DUP1 00000485: ISZERO 00000486: PUSH2 0x048e 00000489: JUMPI 0000048a: PUSH1 0x00 0000048c: DUP1 0000048d: REVERT 0000048e: JUMPDEST 0000048f: POP 00000490: PUSH2 0x01d2 00000493: PUSH2 0x0e03 00000496: JUMP 00000497: JUMPDEST 00000498: CALLVALUE 00000499: DUP1 0000049a: ISZERO 0000049b: PUSH2 0x04a3 0000049e: JUMPI 0000049f: PUSH1 0x00 000004a1: DUP1 000004a2: REVERT 000004a3: JUMPDEST 000004a4: POP 000004a5: PUSH2 0x04ac 000004a8: PUSH2 0x0e70 000004ab: JUMP 000004ac: JUMPDEST 000004ad: PUSH1 0x40 000004af: DUP1 000004b0: MLOAD 000004b1: PUSH1 0x01 000004b3: PUSH1 0x01 000004b5: PUSH1 0xa0 000004b7: SHL 000004b8: SUB 000004b9: SWAP5 000004ba: DUP6 000004bb: AND 000004bc: DUP2 000004bd: MSTORE 000004be: SWAP3 000004bf: DUP5 000004c0: AND 000004c1: PUSH1 0x20 000004c3: DUP5 000004c4: ADD 000004c5: MSTORE 000004c6: SWAP3 000004c7: AND 000004c8: DUP2 000004c9: DUP4 000004ca: ADD 000004cb: MSTORE 000004cc: SWAP1 000004cd: MLOAD 000004ce: SWAP1 000004cf: DUP2 000004d0: SWAP1 000004d1: SUB 000004d2: PUSH1 0x60 000004d4: ADD 000004d5: SWAP1 000004d6: RETURN 000004d7: JUMPDEST 000004d8: CALLVALUE 000004d9: DUP1 000004da: ISZERO 000004db: PUSH2 0x04e3 000004de: JUMPI 000004df: PUSH1 0x00 000004e1: DUP1 000004e2: REVERT 000004e3: JUMPDEST 000004e4: POP 000004e5: PUSH2 0x01d2 000004e8: PUSH1 0x04 000004ea: DUP1 000004eb: CALLDATASIZE 000004ec: SUB 000004ed: PUSH1 0x40 000004ef: DUP2 000004f0: LT 000004f1: ISZERO 000004f2: PUSH2 0x04fa 000004f5: JUMPI 000004f6: PUSH1 0x00 000004f8: DUP1 000004f9: REVERT 000004fa: JUMPDEST 000004fb: POP 000004fc: PUSH1 0x01 000004fe: PUSH1 0x01 00000500: PUSH1 0xa0 00000502: SHL 00000503: SUB 00000504: DUP2 00000505: CALLDATALOAD 00000506: DUP2 00000507: AND 00000508: SWAP2 00000509: PUSH1 0x20 0000050b: ADD 0000050c: CALLDATALOAD 0000050d: AND 0000050e: PUSH2 0x0e8d 00000511: JUMP 00000512: JUMPDEST 00000513: CALLVALUE 00000514: DUP1 00000515: ISZERO 00000516: PUSH2 0x051e 00000519: JUMPI 0000051a: PUSH1 0x00 0000051c: DUP1 0000051d: REVERT 0000051e: JUMPDEST 0000051f: POP 00000520: PUSH2 0x01d2 00000523: PUSH2 0x1038 00000526: JUMP 00000527: JUMPDEST 00000528: CALLVALUE 00000529: DUP1 0000052a: ISZERO 0000052b: PUSH2 0x0533 0000052e: JUMPI 0000052f: PUSH1 0x00 00000531: DUP1 00000532: REVERT 00000533: JUMPDEST 00000534: POP 00000535: PUSH2 0x01fe 00000538: PUSH1 0x04 0000053a: DUP1 0000053b: CALLDATASIZE 0000053c: SUB 0000053d: PUSH1 0x20 0000053f: DUP2 00000540: LT 00000541: ISZERO 00000542: PUSH2 0x054a 00000545: JUMPI 00000546: PUSH1 0x00 00000548: DUP1 00000549: REVERT 0000054a: JUMPDEST 0000054b: POP 0000054c: CALLDATALOAD 0000054d: PUSH2 0x10a9 00000550: JUMP 00000551: JUMPDEST 00000552: CALLVALUE 00000553: DUP1 00000554: ISZERO 00000555: PUSH2 0x055d 00000558: JUMPI 00000559: PUSH1 0x00 0000055b: DUP1 0000055c: REVERT 0000055d: JUMPDEST 0000055e: POP 0000055f: PUSH2 0x01fe 00000562: PUSH2 0x10cc 00000565: JUMP 00000566: JUMPDEST 00000567: CALLVALUE 00000568: DUP1 00000569: ISZERO 0000056a: PUSH2 0x0572 0000056d: JUMPI 0000056e: PUSH1 0x00 00000570: DUP1 00000571: REVERT 00000572: JUMPDEST 00000573: POP 00000574: PUSH2 0x01d2 00000577: PUSH1 0x04 00000579: DUP1 0000057a: CALLDATASIZE 0000057b: SUB 0000057c: PUSH1 0x20 0000057e: DUP2 0000057f: LT 00000580: ISZERO 00000581: PUSH2 0x0589 00000584: JUMPI 00000585: PUSH1 0x00 00000587: DUP1 00000588: REVERT 00000589: JUMPDEST 0000058a: POP 0000058b: CALLDATALOAD 0000058c: PUSH2 0x10d2 0000058f: JUMP 00000590: JUMPDEST 00000591: CALLVALUE 00000592: DUP1 00000593: ISZERO 00000594: PUSH2 0x059c 00000597: JUMPI 00000598: PUSH1 0x00 0000059a: DUP1 0000059b: REVERT 0000059c: JUMPDEST 0000059d: POP 0000059e: PUSH2 0x01d2 000005a1: PUSH2 0x1121 000005a4: JUMP 000005a5: JUMPDEST 000005a6: PUSH2 0x01d2 000005a9: PUSH1 0x04 000005ab: DUP1 000005ac: CALLDATASIZE 000005ad: SUB 000005ae: PUSH1 0x20 000005b0: DUP2 000005b1: LT 000005b2: ISZERO 000005b3: PUSH2 0x05bb 000005b6: JUMPI 000005b7: PUSH1 0x00 000005b9: DUP1 000005ba: REVERT 000005bb: JUMPDEST 000005bc: POP 000005bd: CALLDATALOAD 000005be: PUSH1 0x01 000005c0: PUSH1 0x01 000005c2: PUSH1 0xa0 000005c4: SHL 000005c5: SUB 000005c6: AND 000005c7: PUSH2 0x0617 000005ca: JUMP 000005cb: JUMPDEST 000005cc: CALLVALUE 000005cd: DUP1 000005ce: ISZERO 000005cf: PUSH2 0x05d7 000005d2: JUMPI 000005d3: PUSH1 0x00 000005d5: DUP1 000005d6: REVERT 000005d7: JUMPDEST 000005d8: POP 000005d9: PUSH2 0x01d2 000005dc: PUSH1 0x04 000005de: DUP1 000005df: CALLDATASIZE 000005e0: SUB 000005e1: PUSH1 0x20 000005e3: DUP2 000005e4: LT 000005e5: ISZERO 000005e6: PUSH2 0x05ee 000005e9: JUMPI 000005ea: PUSH1 0x00 000005ec: DUP1 000005ed: REVERT 000005ee: JUMPDEST 000005ef: POP 000005f0: CALLDATALOAD 000005f1: PUSH1 0x01 000005f3: PUSH1 0x01 000005f5: PUSH1 0xa0 000005f7: SHL 000005f8: SUB 000005f9: AND 000005fa: PUSH2 0x1129 000005fd: JUMP 000005fe: JUMPDEST 000005ff: CALLVALUE 00000600: DUP1 00000601: ISZERO 00000602: PUSH2 0x060a 00000605: JUMPI 00000606: PUSH1 0x00 00000608: DUP1 00000609: REVERT 0000060a: JUMPDEST 0000060b: POP 0000060c: PUSH2 0x0451 0000060f: PUSH2 0x117c 00000612: JUMP 00000613: JUMPDEST 00000614: CALLER 00000615: SWAP1 00000616: JUMP 00000617: JUMPDEST 00000618: PUSH2 0x061f 0000061b: PUSH2 0x118b 0000061e: JUMP 0000061f: JUMPDEST 00000620: PUSH2 0x0629 00000623: CALLER 00000624: CALLVALUE 00000625: PUSH2 0x143d 00000628: JUMP 00000629: JUMPDEST 0000062a: CALLVALUE 0000062b: PUSH2 0x0634 0000062e: DUP3 0000062f: DUP3 00000630: PUSH2 0x169c 00000633: JUMP 00000634: JUMPDEST 00000635: PUSH1 0x00 00000637: PUSH2 0x063f 0000063a: DUP3 0000063b: PUSH2 0x16f7 0000063e: JUMP 0000063f: JUMPDEST 00000640: PUSH1 0x06 00000642: SLOAD 00000643: SWAP1 00000644: SWAP2 00000645: POP 00000646: PUSH2 0x0655 00000649: SWAP1 0000064a: DUP4 0000064b: PUSH4 0xffffffff 00000650: PUSH2 0x172c 00000653: AND 00000654: JUMP 00000655: JUMPDEST 00000656: PUSH1 0x06 00000658: SSTORE 00000659: PUSH2 0x0662 0000065c: DUP4 0000065d: DUP3 0000065e: PUSH2 0x1790 00000661: JUMP 00000662: JUMPDEST 00000663: DUP3 00000664: PUSH1 0x01 00000666: PUSH1 0x01 00000668: PUSH1 0xa0 0000066a: SHL 0000066b: SUB 0000066c: AND 0000066d: PUSH2 0x0674 00000670: PUSH2 0x0613 00000673: JUMP 00000674: JUMPDEST 00000675: PUSH1 0x01 00000677: PUSH1 0x01 00000679: PUSH1 0xa0 0000067b: SHL 0000067c: SUB 0000067d: AND 0000067e: PUSH32 0x6faf93231a456e552dbc9961f58d9713ee4f2e69d15f1975b050ef0911053a7b 0000069f: DUP5 000006a0: DUP5 000006a1: PUSH1 0x40 000006a3: MLOAD 000006a4: DUP1 000006a5: DUP4 000006a6: DUP2 000006a7: MSTORE 000006a8: PUSH1 0x20 000006aa: ADD 000006ab: DUP3 000006ac: DUP2 000006ad: MSTORE 000006ae: PUSH1 0x20 000006b0: ADD 000006b1: SWAP3 000006b2: POP 000006b3: POP 000006b4: POP 000006b5: PUSH1 0x40 000006b7: MLOAD 000006b8: DUP1 000006b9: SWAP2 000006ba: SUB 000006bb: SWAP1 000006bc: LOG3 000006bd: PUSH2 0x06c6 000006c0: DUP4 000006c1: DUP4 000006c2: PUSH2 0x1698 000006c5: JUMP 000006c6: JUMPDEST 000006c7: PUSH2 0x06ce 000006ca: PUSH2 0x179a 000006cd: JUMP 000006ce: JUMPDEST 000006cf: PUSH2 0x06d8 000006d2: DUP4 000006d3: DUP4 000006d4: PUSH2 0x1698 000006d7: JUMP 000006d8: JUMPDEST 000006d9: PUSH2 0x0708 000006dc: DUP3 000006dd: PUSH1 0x03 000006df: PUSH1 0x04 000006e1: SLOAD 000006e2: DUP2 000006e3: SLOAD 000006e4: DUP2 000006e5: LT 000006e6: PUSH2 0x06eb 000006e9: JUMPI 000006ea: INVALID 000006eb: JUMPDEST 000006ec: PUSH1 0x00 000006ee: SWAP2 000006ef: DUP3 000006f0: MSTORE 000006f1: PUSH1 0x20 000006f3: SWAP1 000006f4: SWAP2 000006f5: KECCAK256 000006f6: PUSH1 0x02 000006f8: SWAP1 000006f9: SWAP2 000006fa: MUL 000006fb: ADD 000006fc: SLOAD 000006fd: SWAP1 000006fe: PUSH4 0xffffffff 00000703: PUSH2 0x172c 00000706: AND 00000707: JUMP 00000708: JUMPDEST 00000709: PUSH1 0x03 0000070b: PUSH1 0x04 0000070d: SLOAD 0000070e: DUP2 0000070f: SLOAD 00000710: DUP2 00000711: LT 00000712: PUSH2 0x0717 00000715: JUMPI 00000716: INVALID 00000717: JUMPDEST 00000718: PUSH1 0x00 0000071a: SWAP2 0000071b: DUP3 0000071c: MSTORE 0000071d: PUSH1 0x20 0000071f: SWAP1 00000720: SWAP2 00000721: KECCAK256 00000722: PUSH1 0x02 00000724: SWAP1 00000725: SWAP2 00000726: MUL 00000727: ADD 00000728: SSTORE 00000729: POP 0000072a: POP 0000072b: POP 0000072c: JUMP 0000072d: JUMPDEST 0000072e: PUSH2 0x073d 00000731: PUSH2 0x0738 00000734: PUSH2 0x0613 00000737: JUMP 00000738: JUMPDEST 00000739: PUSH2 0x082b 0000073c: JUMP 0000073d: JUMPDEST 0000073e: PUSH2 0x077b 00000741: JUMPI 00000742: PUSH1 0x40 00000744: MLOAD 00000745: PUSH1 0x01 00000747: PUSH1 0xe5 00000749: SHL 0000074a: PUSH3 0x461bcd 0000074e: MUL 0000074f: DUP2 00000750: MSTORE 00000751: PUSH1 0x04 00000753: ADD 00000754: DUP1 00000755: DUP1 00000756: PUSH1 0x20 00000758: ADD 00000759: DUP3 0000075a: DUP2 0000075b: SUB 0000075c: DUP3 0000075d: MSTORE 0000075e: PUSH1 0x30 00000760: DUP2 00000761: MSTORE 00000762: PUSH1 0x20 00000764: ADD 00000765: DUP1 00000766: PUSH2 0x218a 00000769: PUSH1 0x30 0000076b: SWAP2 0000076c: CODECOPY 0000076d: PUSH1 0x40 0000076f: ADD 00000770: SWAP2 00000771: POP 00000772: POP 00000773: PUSH1 0x40 00000775: MLOAD 00000776: DUP1 00000777: SWAP2 00000778: SUB 00000779: SWAP1 0000077a: REVERT 0000077b: JUMPDEST 0000077c: PUSH1 0x0e 0000077e: SLOAD 0000077f: PUSH1 0xff 00000781: AND 00000782: PUSH2 0x07d5 00000785: JUMPI 00000786: PUSH1 0x40 00000788: DUP1 00000789: MLOAD 0000078a: PUSH1 0x01 0000078c: PUSH1 0xe5 0000078e: SHL 0000078f: PUSH3 0x461bcd 00000793: MUL 00000794: DUP2 00000795: MSTORE 00000796: PUSH1 0x20 00000798: PUSH1 0x04 0000079a: DUP3 0000079b: ADD 0000079c: MSTORE 0000079d: PUSH1 0x14 0000079f: PUSH1 0x24 000007a1: DUP3 000007a2: ADD 000007a3: MSTORE 000007a4: PUSH32 0x5061757361626c653a206e6f7420706175736564000000000000000000000000 000007c5: PUSH1 0x44 000007c7: DUP3 000007c8: ADD 000007c9: MSTORE 000007ca: SWAP1 000007cb: MLOAD 000007cc: SWAP1 000007cd: DUP2 000007ce: SWAP1 000007cf: SUB 000007d0: PUSH1 0x64 000007d2: ADD 000007d3: SWAP1 000007d4: REVERT 000007d5: JUMPDEST 000007d6: PUSH1 0x0e 000007d8: DUP1 000007d9: SLOAD 000007da: PUSH1 0xff 000007dc: NOT 000007dd: AND 000007de: SWAP1 000007df: SSTORE 000007e0: PUSH32 0x5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa 00000801: PUSH2 0x0808 00000804: PUSH2 0x0613 00000807: JUMP 00000808: JUMPDEST 00000809: PUSH1 0x40 0000080b: DUP1 0000080c: MLOAD 0000080d: PUSH1 0x01 0000080f: PUSH1 0x01 00000811: PUSH1 0xa0 00000813: SHL 00000814: SUB 00000815: SWAP1 00000816: SWAP3 00000817: AND 00000818: DUP3 00000819: MSTORE 0000081a: MLOAD 0000081b: SWAP1 0000081c: DUP2 0000081d: SWAP1 0000081e: SUB 0000081f: PUSH1 0x20 00000821: ADD 00000822: SWAP1 00000823: LOG1 00000824: JUMP 00000825: JUMPDEST 00000826: PUSH1 0x06 00000828: SLOAD 00000829: SWAP1 0000082a: JUMP 0000082b: JUMPDEST 0000082c: PUSH1 0x00 0000082e: PUSH2 0x083e 00000831: PUSH1 0x0d 00000833: DUP4 00000834: PUSH4 0xffffffff 00000839: PUSH2 0x19af 0000083c: AND 0000083d: JUMP 0000083e: JUMPDEST 0000083f: SWAP3 00000840: SWAP2 00000841: POP 00000842: POP 00000843: JUMP 00000844: JUMPDEST 00000845: PUSH1 0x0b 00000847: SLOAD 00000848: SWAP1 00000849: JUMP 0000084a: JUMPDEST 0000084b: PUSH1 0x00 0000084d: PUSH1 0x02 0000084f: PUSH1 0x04 00000851: SLOAD 00000852: DUP2 00000853: SLOAD 00000854: DUP2 00000855: LT 00000856: PUSH2 0x085b 00000859: JUMPI 0000085a: INVALID 0000085b: JUMPDEST 0000085c: SWAP1 0000085d: PUSH1 0x00 0000085f: MSTORE 00000860: PUSH1 0x20 00000862: PUSH1 0x00 00000864: KECCAK256 00000865: SWAP1 00000866: PUSH1 0x07 00000868: MUL 00000869: ADD 0000086a: PUSH1 0x00 0000086c: ADD 0000086d: SLOAD 0000086e: SWAP1 0000086f: POP 00000870: SWAP1 00000871: JUMP 00000872: JUMPDEST 00000873: PUSH1 0x0e 00000875: SLOAD 00000876: PUSH1 0xff 00000878: AND 00000879: SWAP1 0000087a: JUMP 0000087b: JUMPDEST 0000087c: PUSH1 0x00 0000087e: PUSH1 0x02 00000880: PUSH1 0x04 00000882: SLOAD 00000883: DUP2 00000884: SLOAD 00000885: DUP2 00000886: LT 00000887: PUSH2 0x088c 0000088a: JUMPI 0000088b: INVALID 0000088c: JUMPDEST 0000088d: SWAP1 0000088e: PUSH1 0x00 00000890: MSTORE 00000891: PUSH1 0x20 00000893: PUSH1 0x00 00000895: KECCAK256 00000896: SWAP1 00000897: PUSH1 0x07 00000899: MUL 0000089a: ADD 0000089b: PUSH1 0x01 0000089d: ADD 0000089e: SLOAD 0000089f: SWAP1 000008a0: POP 000008a1: SWAP1 000008a2: JUMP 000008a3: JUMPDEST 000008a4: PUSH2 0x08ab 000008a7: PUSH2 0x0dda 000008aa: JUMP 000008ab: JUMPDEST 000008ac: PUSH2 0x08ed 000008af: JUMPI 000008b0: PUSH1 0x40 000008b2: DUP1 000008b3: MLOAD 000008b4: PUSH1 0x01 000008b6: PUSH1 0xe5 000008b8: SHL 000008b9: PUSH3 0x461bcd 000008bd: MUL 000008be: DUP2 000008bf: MSTORE 000008c0: PUSH1 0x20 000008c2: PUSH1 0x04 000008c4: DUP3 000008c5: ADD 000008c6: DUP2 000008c7: SWAP1 000008c8: MSTORE 000008c9: PUSH1 0x24 000008cb: DUP3 000008cc: ADD 000008cd: MSTORE 000008ce: PUSH1 0x00 000008d0: DUP1 000008d1: MLOAD 000008d2: PUSH1 0x20 000008d4: PUSH2 0x228e 000008d7: DUP4 000008d8: CODECOPY 000008d9: DUP2 000008da: MLOAD 000008db: SWAP2 000008dc: MSTORE 000008dd: PUSH1 0x44 000008df: DUP3 000008e0: ADD 000008e1: MSTORE 000008e2: SWAP1 000008e3: MLOAD 000008e4: SWAP1 000008e5: DUP2 000008e6: SWAP1 000008e7: SUB 000008e8: PUSH1 0x64 000008ea: ADD 000008eb: SWAP1 000008ec: REVERT 000008ed: JUMPDEST 000008ee: ADDRESS 000008ef: BALANCE 000008f0: DUP1 000008f1: PUSH2 0x0944 000008f4: JUMPI 000008f5: PUSH1 0x40 000008f7: DUP1 000008f8: MLOAD 000008f9: PUSH1 0x01 000008fb: PUSH1 0xe5 000008fd: SHL 000008fe: PUSH3 0x461bcd 00000902: MUL 00000903: DUP2 00000904: MSTORE 00000905: PUSH1 0x20 00000907: PUSH1 0x04 00000909: DUP3 0000090a: ADD 0000090b: DUP2 0000090c: SWAP1 0000090d: MSTORE 0000090e: PUSH1 0x24 00000910: DUP3 00000911: ADD 00000912: MSTORE 00000913: PUSH32 0x43726f776473616c653a206e6f20746f6b656e7320746f207472616e73666572 00000934: PUSH1 0x44 00000936: DUP3 00000937: ADD 00000938: MSTORE 00000939: SWAP1 0000093a: MLOAD 0000093b: SWAP1 0000093c: DUP2 0000093d: SWAP1 0000093e: SUB 0000093f: PUSH1 0x64 00000941: ADD 00000942: SWAP1 00000943: REVERT 00000944: JUMPDEST 00000945: PUSH1 0x40 00000947: MLOAD 00000948: PUSH1 0x01 0000094a: PUSH1 0x01 0000094c: PUSH1 0xa0 0000094e: SHL 0000094f: SUB 00000950: DUP4 00000951: AND 00000952: SWAP1 00000953: DUP3 00000954: ISZERO 00000955: PUSH2 0x08fc 00000958: MUL 00000959: SWAP1 0000095a: DUP4 0000095b: SWAP1 0000095c: PUSH1 0x00 0000095e: DUP2 0000095f: DUP2 00000960: DUP2 00000961: DUP6 00000962: DUP9 00000963: DUP9 00000964: CALL 00000965: SWAP4 00000966: POP 00000967: POP 00000968: POP 00000969: POP 0000096a: ISZERO 0000096b: DUP1 0000096c: ISZERO 0000096d: PUSH2 0x097a 00000970: JUMPI 00000971: RETURNDATASIZE 00000972: PUSH1 0x00 00000974: DUP1 00000975: RETURNDATACOPY 00000976: RETURNDATASIZE 00000977: PUSH1 0x00 00000979: REVERT 0000097a: JUMPDEST 0000097b: POP 0000097c: POP 0000097d: POP 0000097e: JUMP 0000097f: JUMPDEST 00000980: PUSH2 0x098f 00000983: PUSH2 0x098a 00000986: PUSH2 0x0613 00000989: JUMP 0000098a: JUMPDEST 0000098b: PUSH2 0x1a19 0000098e: JUMP 0000098f: JUMPDEST 00000990: JUMP 00000991: JUMPDEST 00000992: PUSH2 0x0999 00000995: PUSH2 0x0dda 00000998: JUMP 00000999: JUMPDEST 0000099a: PUSH2 0x09db 0000099d: JUMPI 0000099e: PUSH1 0x40 000009a0: DUP1 000009a1: MLOAD 000009a2: PUSH1 0x01 000009a4: PUSH1 0xe5 000009a6: SHL 000009a7: PUSH3 0x461bcd 000009ab: MUL 000009ac: DUP2 000009ad: MSTORE 000009ae: PUSH1 0x20 000009b0: PUSH1 0x04 000009b2: DUP3 000009b3: ADD 000009b4: DUP2 000009b5: SWAP1 000009b6: MSTORE 000009b7: PUSH1 0x24 000009b9: DUP3 000009ba: ADD 000009bb: MSTORE 000009bc: PUSH1 0x00 000009be: DUP1 000009bf: MLOAD 000009c0: PUSH1 0x20 000009c2: PUSH2 0x228e 000009c5: DUP4 000009c6: CODECOPY 000009c7: DUP2 000009c8: MLOAD 000009c9: SWAP2 000009ca: MSTORE 000009cb: PUSH1 0x44 000009cd: DUP3 000009ce: ADD 000009cf: MSTORE 000009d0: SWAP1 000009d1: MLOAD 000009d2: SWAP1 000009d3: DUP2 000009d4: SWAP1 000009d5: SUB 000009d6: PUSH1 0x64 000009d8: ADD 000009d9: SWAP1 000009da: REVERT 000009db: JUMPDEST 000009dc: PUSH1 0x00 000009de: DUP1 000009df: SLOAD 000009e0: PUSH1 0x40 000009e2: MLOAD 000009e3: PUSH2 0x0100 000009e6: SWAP1 000009e7: SWAP2 000009e8: DIV 000009e9: PUSH1 0x01 000009eb: PUSH1 0x01 000009ed: PUSH1 0xa0 000009ef: SHL 000009f0: SUB 000009f1: AND 000009f2: SWAP1 000009f3: PUSH32 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0 00000a14: SWAP1 00000a15: DUP4 00000a16: SWAP1 00000a17: LOG3 00000a18: PUSH1 0x00 00000a1a: DUP1 00000a1b: SLOAD 00000a1c: PUSH2 0x0100 00000a1f: PUSH1 0x01 00000a21: PUSH1 0xa8 00000a23: SHL 00000a24: SUB 00000a25: NOT 00000a26: AND 00000a27: SWAP1 00000a28: SSTORE 00000a29: JUMP 00000a2a: JUMPDEST 00000a2b: PUSH1 0x0c 00000a2d: PUSH1 0x20 00000a2f: MSTORE 00000a30: PUSH1 0x00 00000a32: SWAP1 00000a33: DUP2 00000a34: MSTORE 00000a35: PUSH1 0x40 00000a37: SWAP1 00000a38: KECCAK256 00000a39: SLOAD 00000a3a: DUP2 00000a3b: JUMP 00000a3c: JUMPDEST 00000a3d: PUSH2 0x0a47 00000a40: PUSH2 0x0738 00000a43: PUSH2 0x0613 00000a46: JUMP 00000a47: JUMPDEST 00000a48: PUSH2 0x0a85 00000a4b: JUMPI 00000a4c: PUSH1 0x40 00000a4e: MLOAD 00000a4f: PUSH1 0x01 00000a51: PUSH1 0xe5 00000a53: SHL 00000a54: PUSH3 0x461bcd 00000a58: MUL 00000a59: DUP2 00000a5a: MSTORE 00000a5b: PUSH1 0x04 00000a5d: ADD 00000a5e: DUP1 00000a5f: DUP1 00000a60: PUSH1 0x20 00000a62: ADD 00000a63: DUP3 00000a64: DUP2 00000a65: SUB 00000a66: DUP3 00000a67: MSTORE 00000a68: PUSH1 0x30 00000a6a: DUP2 00000a6b: MSTORE 00000a6c: PUSH1 0x20 00000a6e: ADD 00000a6f: DUP1 00000a70: PUSH2 0x218a 00000a73: PUSH1 0x30 00000a75: SWAP2 00000a76: CODECOPY 00000a77: PUSH1 0x40 00000a79: ADD 00000a7a: SWAP2 00000a7b: POP 00000a7c: POP 00000a7d: PUSH1 0x40 00000a7f: MLOAD 00000a80: DUP1 00000a81: SWAP2 00000a82: SUB 00000a83: SWAP1 00000a84: REVERT 00000a85: JUMPDEST 00000a86: PUSH2 0x0a8e 00000a89: DUP2 00000a8a: PUSH2 0x1a61 00000a8d: JUMP 00000a8e: JUMPDEST 00000a8f: POP 00000a90: JUMP 00000a91: JUMPDEST 00000a92: PUSH2 0x0a9c 00000a95: PUSH2 0x0738 00000a98: PUSH2 0x0613 00000a9b: JUMP 00000a9c: JUMPDEST 00000a9d: PUSH2 0x0ada 00000aa0: JUMPI 00000aa1: PUSH1 0x40 00000aa3: MLOAD 00000aa4: PUSH1 0x01 00000aa6: PUSH1 0xe5 00000aa8: SHL 00000aa9: PUSH3 0x461bcd 00000aad: MUL 00000aae: DUP2 00000aaf: MSTORE 00000ab0: PUSH1 0x04 00000ab2: ADD 00000ab3: DUP1 00000ab4: DUP1 00000ab5: PUSH1 0x20 00000ab7: ADD 00000ab8: DUP3 00000ab9: DUP2 00000aba: SUB 00000abb: DUP3 00000abc: MSTORE 00000abd: PUSH1 0x30 00000abf: DUP2 00000ac0: MSTORE 00000ac1: PUSH1 0x20 00000ac3: ADD 00000ac4: DUP1 00000ac5: PUSH2 0x218a 00000ac8: PUSH1 0x30 00000aca: SWAP2 00000acb: CODECOPY 00000acc: PUSH1 0x40 00000ace: ADD 00000acf: SWAP2 00000ad0: POP 00000ad1: POP 00000ad2: PUSH1 0x40 00000ad4: MLOAD 00000ad5: DUP1 00000ad6: SWAP2 00000ad7: SUB 00000ad8: SWAP1 00000ad9: REVERT 00000ada: JUMPDEST 00000adb: PUSH1 0x0e 00000add: SLOAD 00000ade: PUSH1 0xff 00000ae0: AND 00000ae1: ISZERO 00000ae2: PUSH2 0x0b2b 00000ae5: JUMPI 00000ae6: PUSH1 0x40 00000ae8: DUP1 00000ae9: MLOAD 00000aea: PUSH1 0x01 00000aec: PUSH1 0xe5 00000aee: SHL 00000aef: PUSH3 0x461bcd 00000af3: MUL 00000af4: DUP2 00000af5: MSTORE 00000af6: PUSH1 0x20 00000af8: PUSH1 0x04 00000afa: DUP3 00000afb: ADD 00000afc: MSTORE 00000afd: PUSH1 0x10 00000aff: PUSH1 0x24 00000b01: DUP3 00000b02: ADD 00000b03: MSTORE 00000b04: PUSH1 0x01 00000b06: PUSH1 0x82 00000b08: SHL 00000b09: PUSH16 0x14185d5cd8589b194e881c185d5cd959 00000b1a: MUL 00000b1b: PUSH1 0x44 00000b1d: DUP3 00000b1e: ADD 00000b1f: MSTORE 00000b20: SWAP1 00000b21: MLOAD 00000b22: SWAP1 00000b23: DUP2 00000b24: SWAP1 00000b25: SUB 00000b26: PUSH1 0x64 00000b28: ADD 00000b29: SWAP1 00000b2a: REVERT 00000b2b: JUMPDEST 00000b2c: PUSH1 0x0e 00000b2e: DUP1 00000b2f: SLOAD 00000b30: PUSH1 0xff 00000b32: NOT 00000b33: AND 00000b34: PUSH1 0x01 00000b36: OR 00000b37: SWAP1 00000b38: SSTORE 00000b39: PUSH32 0x62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258 00000b5a: PUSH2 0x0808 00000b5d: PUSH2 0x0613 00000b60: JUMP 00000b61: JUMPDEST 00000b62: PUSH1 0x04 00000b64: SLOAD 00000b65: DUP2 00000b66: JUMP 00000b67: JUMPDEST 00000b68: PUSH2 0x0b6f 00000b6b: PUSH2 0x0dda 00000b6e: JUMP 00000b6f: JUMPDEST 00000b70: PUSH2 0x0bb1 00000b73: JUMPI 00000b74: PUSH1 0x40 00000b76: DUP1 00000b77: MLOAD 00000b78: PUSH1 0x01 00000b7a: PUSH1 0xe5 00000b7c: SHL 00000b7d: PUSH3 0x461bcd 00000b81: MUL 00000b82: DUP2 00000b83: MSTORE 00000b84: PUSH1 0x20 00000b86: PUSH1 0x04 00000b88: DUP3 00000b89: ADD 00000b8a: DUP2 00000b8b: SWAP1 00000b8c: MSTORE 00000b8d: PUSH1 0x24 00000b8f: DUP3 00000b90: ADD 00000b91: MSTORE 00000b92: PUSH1 0x00 00000b94: DUP1 00000b95: MLOAD 00000b96: PUSH1 0x20 00000b98: PUSH2 0x228e 00000b9b: DUP4 00000b9c: CODECOPY 00000b9d: DUP2 00000b9e: MLOAD 00000b9f: SWAP2 00000ba0: MSTORE 00000ba1: PUSH1 0x44 00000ba3: DUP3 00000ba4: ADD 00000ba5: MSTORE 00000ba6: SWAP1 00000ba7: MLOAD 00000ba8: SWAP1 00000ba9: DUP2 00000baa: SWAP1 00000bab: SUB 00000bac: PUSH1 0x64 00000bae: ADD 00000baf: SWAP1 00000bb0: REVERT 00000bb1: JUMPDEST 00000bb2: PUSH2 0x0bb9 00000bb5: PUSH2 0x2139 00000bb8: JUMP 00000bb9: JUMPDEST 00000bba: PUSH1 0x40 00000bbc: MLOAD 00000bbd: DUP1 00000bbe: PUSH1 0xe0 00000bc0: ADD 00000bc1: PUSH1 0x40 00000bc3: MSTORE 00000bc4: DUP1 00000bc5: PUSH1 0x00 00000bc7: DUP2 00000bc8: MSTORE 00000bc9: PUSH1 0x20 00000bcb: ADD 00000bcc: PUSH1 0x00 00000bce: DUP2 00000bcf: MSTORE 00000bd0: PUSH1 0x20 00000bd2: ADD 00000bd3: DUP8 00000bd4: DUP2 00000bd5: MSTORE 00000bd6: PUSH1 0x20 00000bd8: ADD 00000bd9: DUP7 00000bda: DUP2 00000bdb: MSTORE 00000bdc: PUSH1 0x20 00000bde: ADD 00000bdf: DUP6 00000be0: DUP2 00000be1: MSTORE 00000be2: PUSH1 0x20 00000be4: ADD 00000be5: DUP5 00000be6: DUP2 00000be7: MSTORE 00000be8: PUSH1 0x20 00000bea: ADD 00000beb: DUP4 00000bec: DUP2 00000bed: MSTORE 00000bee: POP 00000bef: SWAP1 00000bf0: POP 00000bf1: PUSH2 0x0bf8 00000bf4: PUSH2 0x2176 00000bf7: JUMP 00000bf8: JUMPDEST 00000bf9: POP 00000bfa: PUSH1 0x40 00000bfc: DUP1 00000bfd: MLOAD 00000bfe: PUSH1 0x20 00000c00: DUP1 00000c01: DUP3 00000c02: ADD 00000c03: DUP4 00000c04: MSTORE 00000c05: PUSH1 0x00 00000c07: DUP1 00000c08: DUP4 00000c09: MSTORE 00000c0a: PUSH1 0x02 00000c0c: DUP1 00000c0d: SLOAD 00000c0e: PUSH1 0x01 00000c10: DUP2 00000c11: DUP2 00000c12: ADD 00000c13: DUP4 00000c14: SSTORE 00000c15: DUP3 00000c16: DUP5 00000c17: MSTORE 00000c18: DUP8 00000c19: MLOAD 00000c1a: PUSH1 0x07 00000c1c: SWAP1 00000c1d: SWAP3 00000c1e: MUL 00000c1f: PUSH32 0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace 00000c40: DUP2 00000c41: ADD 00000c42: SWAP3 00000c43: SWAP1 00000c44: SWAP3 00000c45: SSTORE 00000c46: SWAP4 00000c47: DUP8 00000c48: ADD 00000c49: MLOAD 00000c4a: PUSH32 0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf 00000c6b: DUP3 00000c6c: ADD 00000c6d: SSTORE 00000c6e: SWAP5 00000c6f: DUP7 00000c70: ADD 00000c71: MLOAD 00000c72: PUSH32 0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad0 00000c93: DUP7 00000c94: ADD 00000c95: SSTORE 00000c96: PUSH1 0x60 00000c98: DUP7 00000c99: ADD 00000c9a: MLOAD 00000c9b: PUSH32 0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad1 00000cbc: DUP7 00000cbd: ADD 00000cbe: SSTORE 00000cbf: PUSH1 0x80 00000cc1: DUP7 00000cc2: ADD 00000cc3: MLOAD 00000cc4: PUSH32 0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad2 00000ce5: DUP7 00000ce6: ADD 00000ce7: SSTORE 00000ce8: PUSH1 0xa0 00000cea: DUP7 00000ceb: ADD 00000cec: MLOAD 00000ced: PUSH32 0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad3 00000d0e: DUP7 00000d0f: ADD 00000d10: SSTORE 00000d11: PUSH1 0xc0 00000d13: SWAP1 00000d14: SWAP6 00000d15: ADD 00000d16: MLOAD 00000d17: PUSH32 0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ad4 00000d38: SWAP1 00000d39: SWAP5 00000d3a: ADD 00000d3b: SWAP4 00000d3c: SWAP1 00000d3d: SWAP4 00000d3e: SSTORE 00000d3f: PUSH1 0x03 00000d41: DUP1 00000d42: SLOAD 00000d43: SWAP2 00000d44: DUP3 00000d45: ADD 00000d46: DUP2 00000d47: SSTORE 00000d48: SWAP1 00000d49: SWAP3 00000d4a: MSTORE 00000d4b: MLOAD 00000d4c: SWAP2 00000d4d: MUL 00000d4e: PUSH32 0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b 00000d6f: ADD 00000d70: SSTORE 00000d71: POP 00000d72: POP 00000d73: POP 00000d74: POP 00000d75: POP 00000d76: JUMP 00000d77: JUMPDEST 00000d78: PUSH1 0x02 00000d7a: DUP2 00000d7b: DUP2 00000d7c: SLOAD 00000d7d: DUP2 00000d7e: LT 00000d7f: PUSH2 0x0d84 00000d82: JUMPI 00000d83: INVALID 00000d84: JUMPDEST 00000d85: SWAP1 00000d86: PUSH1 0x00 00000d88: MSTORE 00000d89: PUSH1 0x20 00000d8b: PUSH1 0x00 00000d8d: KECCAK256 00000d8e: SWAP1 00000d8f: PUSH1 0x07 00000d91: MUL 00000d92: ADD 00000d93: PUSH1 0x00 00000d95: SWAP2 00000d96: POP 00000d97: SWAP1 00000d98: POP 00000d99: DUP1 00000d9a: PUSH1 0x00 00000d9c: ADD 00000d9d: SLOAD 00000d9e: SWAP1 00000d9f: DUP1 00000da0: PUSH1 0x01 00000da2: ADD 00000da3: SLOAD 00000da4: SWAP1 00000da5: DUP1 00000da6: PUSH1 0x02 00000da8: ADD 00000da9: SLOAD 00000daa: SWAP1 00000dab: DUP1 00000dac: PUSH1 0x03 00000dae: ADD 00000daf: SLOAD 00000db0: SWAP1 00000db1: DUP1 00000db2: PUSH1 0x04 00000db4: ADD 00000db5: SLOAD 00000db6: SWAP1 00000db7: DUP1 00000db8: PUSH1 0x05 00000dba: ADD 00000dbb: SLOAD 00000dbc: SWAP1 00000dbd: DUP1 00000dbe: PUSH1 0x06 00000dc0: ADD 00000dc1: SLOAD 00000dc2: SWAP1 00000dc3: POP 00000dc4: DUP8 00000dc5: JUMP 00000dc6: JUMPDEST 00000dc7: PUSH1 0x00 00000dc9: SLOAD 00000dca: PUSH2 0x0100 00000dcd: SWAP1 00000dce: DIV 00000dcf: PUSH1 0x01 00000dd1: PUSH1 0x01 00000dd3: PUSH1 0xa0 00000dd5: SHL 00000dd6: SUB 00000dd7: AND 00000dd8: SWAP1 00000dd9: JUMP 00000dda: JUMPDEST 00000ddb: PUSH1 0x00 00000ddd: DUP1 00000dde: SLOAD 00000ddf: PUSH2 0x0100 00000de2: SWAP1 00000de3: DIV 00000de4: PUSH1 0x01 00000de6: PUSH1 0x01 00000de8: PUSH1 0xa0 00000dea: SHL 00000deb: SUB 00000dec: AND 00000ded: PUSH2 0x0df4 00000df0: PUSH2 0x0613 00000df3: JUMP 00000df4: JUMPDEST 00000df5: PUSH1 0x01 00000df7: PUSH1 0x01 00000df9: PUSH1 0xa0 00000dfb: SHL 00000dfc: SUB 00000dfd: AND 00000dfe: EQ 00000dff: SWAP1 00000e00: POP 00000e01: SWAP1 00000e02: JUMP 00000e03: JUMPDEST 00000e04: PUSH2 0x0e0b 00000e07: PUSH2 0x0dda 00000e0a: JUMP 00000e0b: JUMPDEST 00000e0c: PUSH2 0x0e4d 00000e0f: JUMPI 00000e10: PUSH1 0x40 00000e12: DUP1 00000e13: MLOAD 00000e14: PUSH1 0x01 00000e16: PUSH1 0xe5 00000e18: SHL 00000e19: PUSH3 0x461bcd 00000e1d: MUL 00000e1e: DUP2 00000e1f: MSTORE 00000e20: PUSH1 0x20 00000e22: PUSH1 0x04 00000e24: DUP3 00000e25: ADD 00000e26: DUP2 00000e27: SWAP1 00000e28: MSTORE 00000e29: PUSH1 0x24 00000e2b: DUP3 00000e2c: ADD 00000e2d: MSTORE 00000e2e: PUSH1 0x00 00000e30: DUP1 00000e31: MLOAD 00000e32: PUSH1 0x20 00000e34: PUSH2 0x228e 00000e37: DUP4 00000e38: CODECOPY 00000e39: DUP2 00000e3a: MLOAD 00000e3b: SWAP2 00000e3c: MSTORE 00000e3d: PUSH1 0x44 00000e3f: DUP3 00000e40: ADD 00000e41: MSTORE 00000e42: SWAP1 00000e43: MLOAD 00000e44: SWAP1 00000e45: DUP2 00000e46: SWAP1 00000e47: SUB 00000e48: PUSH1 0x64 00000e4a: ADD 00000e4b: SWAP1 00000e4c: REVERT 00000e4d: JUMPDEST 00000e4e: TIMESTAMP 00000e4f: PUSH1 0x02 00000e51: PUSH1 0x04 00000e53: SLOAD 00000e54: DUP2 00000e55: SLOAD 00000e56: DUP2 00000e57: LT 00000e58: PUSH2 0x0e5d 00000e5b: JUMPI 00000e5c: INVALID 00000e5d: JUMPDEST 00000e5e: PUSH1 0x00 00000e60: SWAP2 00000e61: DUP3 00000e62: MSTORE 00000e63: PUSH1 0x20 00000e65: SWAP1 00000e66: SWAP2 00000e67: KECCAK256 00000e68: PUSH1 0x07 00000e6a: SWAP1 00000e6b: SWAP2 00000e6c: MUL 00000e6d: ADD 00000e6e: SSTORE 00000e6f: JUMP 00000e70: JUMPDEST 00000e71: PUSH1 0x08 00000e73: SLOAD 00000e74: PUSH1 0x09 00000e76: SLOAD 00000e77: PUSH1 0x0a 00000e79: SLOAD 00000e7a: PUSH1 0x01 00000e7c: PUSH1 0x01 00000e7e: PUSH1 0xa0 00000e80: SHL 00000e81: SUB 00000e82: SWAP3 00000e83: DUP4 00000e84: AND 00000e85: SWAP4 00000e86: SWAP2 00000e87: DUP4 00000e88: AND 00000e89: SWAP3 00000e8a: AND 00000e8b: SWAP1 00000e8c: JUMP 00000e8d: JUMPDEST 00000e8e: PUSH2 0x0e95 00000e91: PUSH2 0x0dda 00000e94: JUMP 00000e95: JUMPDEST 00000e96: PUSH2 0x0ed7 00000e99: JUMPI 00000e9a: PUSH1 0x40 00000e9c: DUP1 00000e9d: MLOAD 00000e9e: PUSH1 0x01 00000ea0: PUSH1 0xe5 00000ea2: SHL 00000ea3: PUSH3 0x461bcd 00000ea7: MUL 00000ea8: DUP2 00000ea9: MSTORE 00000eaa: PUSH1 0x20 00000eac: PUSH1 0x04 00000eae: DUP3 00000eaf: ADD 00000eb0: DUP2 00000eb1: SWAP1 00000eb2: MSTORE 00000eb3: PUSH1 0x24 00000eb5: DUP3 00000eb6: ADD 00000eb7: MSTORE 00000eb8: PUSH1 0x00 00000eba: DUP1 00000ebb: MLOAD 00000ebc: PUSH1 0x20 00000ebe: PUSH2 0x228e 00000ec1: DUP4 00000ec2: CODECOPY 00000ec3: DUP2 00000ec4: MLOAD 00000ec5: SWAP2 00000ec6: MSTORE 00000ec7: PUSH1 0x44 00000ec9: DUP3 00000eca: ADD 00000ecb: MSTORE 00000ecc: SWAP1 00000ecd: MLOAD 00000ece: SWAP1 00000ecf: DUP2 00000ed0: SWAP1 00000ed1: SUB 00000ed2: PUSH1 0x64 00000ed4: ADD 00000ed5: SWAP1 00000ed6: REVERT 00000ed7: JUMPDEST 00000ed8: PUSH1 0x40 00000eda: DUP1 00000edb: MLOAD 00000edc: PUSH1 0x01 00000ede: PUSH1 0xe0 00000ee0: SHL 00000ee1: PUSH4 0x70a08231 00000ee6: MUL 00000ee7: DUP2 00000ee8: MSTORE 00000ee9: ADDRESS 00000eea: PUSH1 0x04 00000eec: DUP3 00000eed: ADD 00000eee: MSTORE 00000eef: SWAP1 00000ef0: MLOAD 00000ef1: PUSH1 0x00 00000ef3: SWAP2 00000ef4: PUSH1 0x01 00000ef6: PUSH1 0x01 00000ef8: PUSH1 0xa0 00000efa: SHL 00000efb: SUB 00000efc: DUP6 00000efd: AND 00000efe: SWAP2 00000eff: PUSH4 0x70a08231 00000f04: SWAP2 00000f05: PUSH1 0x24 00000f07: DUP1 00000f08: DUP3 00000f09: ADD 00000f0a: SWAP3 00000f0b: PUSH1 0x20 00000f0d: SWAP3 00000f0e: SWAP1 00000f0f: SWAP2 00000f10: SWAP1 00000f11: DUP3 00000f12: SWAP1 00000f13: SUB 00000f14: ADD 00000f15: DUP2 00000f16: DUP7 00000f17: DUP1 00000f18: EXTCODESIZE 00000f19: ISZERO 00000f1a: DUP1 00000f1b: ISZERO 00000f1c: PUSH2 0x0f24 00000f1f: JUMPI 00000f20: PUSH1 0x00 00000f22: DUP1 00000f23: REVERT 00000f24: JUMPDEST 00000f25: POP 00000f26: GAS 00000f27: STATICCALL 00000f28: ISZERO 00000f29: DUP1 00000f2a: ISZERO 00000f2b: PUSH2 0x0f38 00000f2e: JUMPI 00000f2f: RETURNDATASIZE 00000f30: PUSH1 0x00 00000f32: DUP1 00000f33: RETURNDATACOPY 00000f34: RETURNDATASIZE 00000f35: PUSH1 0x00 00000f37: REVERT 00000f38: JUMPDEST 00000f39: POP 00000f3a: POP 00000f3b: POP 00000f3c: POP 00000f3d: PUSH1 0x40 00000f3f: MLOAD 00000f40: RETURNDATASIZE 00000f41: PUSH1 0x20 00000f43: DUP2 00000f44: LT 00000f45: ISZERO 00000f46: PUSH2 0x0f4e 00000f49: JUMPI 00000f4a: PUSH1 0x00 00000f4c: DUP1 00000f4d: REVERT 00000f4e: JUMPDEST 00000f4f: POP 00000f50: MLOAD 00000f51: SWAP1 00000f52: POP 00000f53: DUP1 00000f54: PUSH2 0x0fa7 00000f57: JUMPI 00000f58: PUSH1 0x40 00000f5a: DUP1 00000f5b: MLOAD 00000f5c: PUSH1 0x01 00000f5e: PUSH1 0xe5 00000f60: SHL 00000f61: PUSH3 0x461bcd 00000f65: MUL 00000f66: DUP2 00000f67: MSTORE 00000f68: PUSH1 0x20 00000f6a: PUSH1 0x04 00000f6c: DUP3 00000f6d: ADD 00000f6e: DUP2 00000f6f: SWAP1 00000f70: MSTORE 00000f71: PUSH1 0x24 00000f73: DUP3 00000f74: ADD 00000f75: MSTORE 00000f76: PUSH32 0x43726f776473616c653a206e6f20746f6b656e7320746f207472616e73666572 00000f97: PUSH1 0x44 00000f99: DUP3 00000f9a: ADD 00000f9b: MSTORE 00000f9c: SWAP1 00000f9d: MLOAD 00000f9e: SWAP1 00000f9f: DUP2 00000fa0: SWAP1 00000fa1: SUB 00000fa2: PUSH1 0x64 00000fa4: ADD 00000fa5: SWAP1 00000fa6: REVERT 00000fa7: JUMPDEST 00000fa8: DUP3 00000fa9: PUSH1 0x01 00000fab: PUSH1 0x01 00000fad: PUSH1 0xa0 00000faf: SHL 00000fb0: SUB 00000fb1: AND 00000fb2: PUSH4 0xa9059cbb 00000fb7: DUP4 00000fb8: DUP4 00000fb9: PUSH1 0x40 00000fbb: MLOAD 00000fbc: DUP4 00000fbd: PUSH4 0xffffffff 00000fc2: AND 00000fc3: PUSH1 0xe0 00000fc5: SHL 00000fc6: DUP2 00000fc7: MSTORE 00000fc8: PUSH1 0x04 00000fca: ADD 00000fcb: DUP1 00000fcc: DUP4 00000fcd: PUSH1 0x01 00000fcf: PUSH1 0x01 00000fd1: PUSH1 0xa0 00000fd3: SHL 00000fd4: SUB 00000fd5: AND 00000fd6: PUSH1 0x01 00000fd8: PUSH1 0x01 00000fda: PUSH1 0xa0 00000fdc: SHL 00000fdd: SUB 00000fde: AND 00000fdf: DUP2 00000fe0: MSTORE 00000fe1: PUSH1 0x20 00000fe3: ADD 00000fe4: DUP3 00000fe5: DUP2 00000fe6: MSTORE 00000fe7: PUSH1 0x20 00000fe9: ADD 00000fea: SWAP3 00000feb: POP 00000fec: POP 00000fed: POP 00000fee: PUSH1 0x20 00000ff0: PUSH1 0x40 00000ff2: MLOAD 00000ff3: DUP1 00000ff4: DUP4 00000ff5: SUB 00000ff6: DUP2 00000ff7: PUSH1 0x00 00000ff9: DUP8 00000ffa: DUP1 00000ffb: EXTCODESIZE 00000ffc: ISZERO 00000ffd: DUP1 00000ffe: ISZERO 00000fff: PUSH2 0x1007 00001002: JUMPI 00001003: PUSH1 0x00 00001005: DUP1 00001006: REVERT 00001007: JUMPDEST 00001008: POP 00001009: GAS 0000100a: CALL 0000100b: ISZERO 0000100c: DUP1 0000100d: ISZERO 0000100e: PUSH2 0x101b 00001011: JUMPI 00001012: RETURNDATASIZE 00001013: PUSH1 0x00 00001015: DUP1 00001016: RETURNDATACOPY 00001017: RETURNDATASIZE 00001018: PUSH1 0x00 0000101a: REVERT 0000101b: JUMPDEST 0000101c: POP 0000101d: POP 0000101e: POP 0000101f: POP 00001020: PUSH1 0x40 00001022: MLOAD 00001023: RETURNDATASIZE 00001024: PUSH1 0x20 00001026: DUP2 00001027: LT 00001028: ISZERO 00001029: PUSH2 0x1031 0000102c: JUMPI 0000102d: PUSH1 0x00 0000102f: DUP1 00001030: REVERT 00001031: JUMPDEST 00001032: POP 00001033: POP 00001034: POP 00001035: POP 00001036: POP 00001037: JUMP 00001038: JUMPDEST 00001039: PUSH2 0x1040 0000103c: PUSH2 0x0dda 0000103f: JUMP 00001040: JUMPDEST 00001041: PUSH2 0x1082 00001044: JUMPI 00001045: PUSH1 0x40 00001047: DUP1 00001048: MLOAD 00001049: PUSH1 0x01 0000104b: PUSH1 0xe5 0000104d: SHL 0000104e: PUSH3 0x461bcd 00001052: MUL 00001053: DUP2 00001054: MSTORE 00001055: PUSH1 0x20 00001057: PUSH1 0x04 00001059: DUP3 0000105a: ADD 0000105b: DUP2 0000105c: SWAP1 0000105d: MSTORE 0000105e: PUSH1 0x24 00001060: DUP3 00001061: ADD 00001062: MSTORE 00001063: PUSH1 0x00 00001065: DUP1 00001066: MLOAD 00001067: PUSH1 0x20 00001069: PUSH2 0x228e 0000106c: DUP4 0000106d: CODECOPY 0000106e: DUP2 0000106f: MLOAD 00001070: SWAP2 00001071: MSTORE 00001072: PUSH1 0x44 00001074: DUP3 00001075: ADD 00001076: MSTORE 00001077: SWAP1 00001078: MLOAD 00001079: SWAP1 0000107a: DUP2 0000107b: SWAP1 0000107c: SUB 0000107d: PUSH1 0x64 0000107f: ADD 00001080: SWAP1 00001081: REVERT 00001082: JUMPDEST 00001083: TIMESTAMP 00001084: PUSH1 0x02 00001086: PUSH1 0x04 00001088: SLOAD 00001089: DUP2 0000108a: SLOAD 0000108b: DUP2 0000108c: LT 0000108d: PUSH2 0x1092 00001090: JUMPI 00001091: INVALID 00001092: JUMPDEST 00001093: SWAP1 00001094: PUSH1 0x00 00001096: MSTORE 00001097: PUSH1 0x20 00001099: PUSH1 0x00 0000109b: KECCAK256 0000109c: SWAP1 0000109d: PUSH1 0x07 0000109f: MUL 000010a0: ADD 000010a1: PUSH1 0x01 000010a3: ADD 000010a4: DUP2 000010a5: SWAP1 000010a6: SSTORE 000010a7: POP 000010a8: JUMP 000010a9: JUMPDEST 000010aa: PUSH1 0x03 000010ac: DUP2 000010ad: DUP2 000010ae: SLOAD 000010af: DUP2 000010b0: LT 000010b1: PUSH2 0x10b6 000010b4: JUMPI 000010b5: INVALID 000010b6: JUMPDEST 000010b7: PUSH1 0x00 000010b9: SWAP2 000010ba: DUP3 000010bb: MSTORE 000010bc: PUSH1 0x20 000010be: SWAP1 000010bf: SWAP2 000010c0: KECCAK256 000010c1: PUSH1 0x02 000010c3: SWAP1 000010c4: SWAP2 000010c5: MUL 000010c6: ADD 000010c7: SLOAD 000010c8: SWAP1 000010c9: POP 000010ca: DUP2 000010cb: JUMP 000010cc: JUMPDEST 000010cd: PUSH1 0x07 000010cf: SLOAD 000010d0: SWAP1 000010d1: JUMP 000010d2: JUMPDEST 000010d3: PUSH2 0x10da 000010d6: PUSH2 0x0dda 000010d9: JUMP 000010da: JUMPDEST 000010db: PUSH2 0x111c 000010de: JUMPI 000010df: PUSH1 0x40 000010e1: DUP1 000010e2: MLOAD 000010e3: PUSH1 0x01 000010e5: PUSH1 0xe5 000010e7: SHL 000010e8: PUSH3 0x461bcd 000010ec: MUL 000010ed: DUP2 000010ee: MSTORE 000010ef: PUSH1 0x20 000010f1: PUSH1 0x04 000010f3: DUP3 000010f4: ADD 000010f5: DUP2 000010f6: SWAP1 000010f7: MSTORE 000010f8: PUSH1 0x24 000010fa: DUP3 000010fb: ADD 000010fc: MSTORE 000010fd: PUSH1 0x00 000010ff: DUP1 00001100: MLOAD 00001101: PUSH1 0x20 00001103: PUSH2 0x228e 00001106: DUP4 00001107: CODECOPY 00001108: DUP2 00001109: MLOAD 0000110a: SWAP2 0000110b: MSTORE 0000110c: PUSH1 0x44 0000110e: DUP3 0000110f: ADD 00001110: MSTORE 00001111: SWAP1 00001112: MLOAD 00001113: SWAP1 00001114: DUP2 00001115: SWAP1 00001116: SUB 00001117: PUSH1 0x64 00001119: ADD 0000111a: SWAP1 0000111b: REVERT 0000111c: JUMPDEST 0000111d: PUSH1 0x0b 0000111f: SSTORE 00001120: JUMP 00001121: JUMPDEST 00001122: PUSH2 0x098f 00001125: PUSH2 0x118b 00001128: JUMP 00001129: JUMPDEST 0000112a: PUSH2 0x1131 0000112d: PUSH2 0x0dda 00001130: JUMP 00001131: JUMPDEST 00001132: PUSH2 0x1173 00001135: JUMPI 00001136: PUSH1 0x40 00001138: DUP1 00001139: MLOAD 0000113a: PUSH1 0x01 0000113c: PUSH1 0xe5 0000113e: SHL 0000113f: PUSH3 0x461bcd 00001143: MUL 00001144: DUP2 00001145: MSTORE 00001146: PUSH1 0x20 00001148: PUSH1 0x04 0000114a: DUP3 0000114b: ADD 0000114c: DUP2 0000114d: SWAP1 0000114e: MSTORE 0000114f: PUSH1 0x24 00001151: DUP3 00001152: ADD 00001153: MSTORE 00001154: PUSH1 0x00 00001156: DUP1 00001157: MLOAD 00001158: PUSH1 0x20 0000115a: PUSH2 0x228e 0000115d: DUP4 0000115e: CODECOPY 0000115f: DUP2 00001160: MLOAD 00001161: SWAP2 00001162: MSTORE 00001163: PUSH1 0x44 00001165: DUP3 00001166: ADD 00001167: MSTORE 00001168: SWAP1 00001169: MLOAD 0000116a: SWAP1 0000116b: DUP2 0000116c: SWAP1 0000116d: SUB 0000116e: PUSH1 0x64 00001170: ADD 00001171: SWAP1 00001172: REVERT 00001173: JUMPDEST 00001174: PUSH2 0x0a8e 00001177: DUP2 00001178: PUSH2 0x1aa9 0000117b: JUMP 0000117c: JUMPDEST 0000117d: PUSH1 0x05 0000117f: SLOAD 00001180: PUSH1 0x01 00001182: PUSH1 0x01 00001184: PUSH1 0xa0 00001186: SHL 00001187: SUB 00001188: AND 00001189: SWAP1 0000118a: JUMP 0000118b: JUMPDEST 0000118c: PUSH1 0x04 0000118e: SLOAD 0000118f: PUSH1 0x02 00001191: DUP1 00001192: SLOAD 00001193: PUSH1 0x01 00001195: DUP4 00001196: ADD 00001197: SWAP3 00001198: TIMESTAMP 00001199: SWAP3 0000119a: SWAP2 0000119b: DUP2 0000119c: LT 0000119d: PUSH2 0x11a2 000011a0: JUMPI 000011a1: INVALID 000011a2: JUMPDEST 000011a3: SWAP1 000011a4: PUSH1 0x00 000011a6: MSTORE 000011a7: PUSH1 0x20 000011a9: PUSH1 0x00 000011ab: KECCAK256 000011ac: SWAP1 000011ad: PUSH1 0x07 000011af: MUL 000011b0: ADD 000011b1: PUSH1 0x01 000011b3: ADD 000011b4: SLOAD 000011b5: LT 000011b6: DUP1 000011b7: ISZERO 000011b8: PUSH2 0x11c2 000011bb: JUMPI 000011bc: POP 000011bd: PUSH1 0x02 000011bf: SLOAD 000011c0: DUP2 000011c1: LT 000011c2: JUMPDEST 000011c3: ISZERO 000011c4: PUSH2 0x130c 000011c7: JUMPI 000011c8: PUSH1 0x04 000011ca: PUSH1 0x00 000011cc: DUP2 000011cd: SLOAD 000011ce: DUP1 000011cf: SWAP3 000011d0: SWAP2 000011d1: SWAP1 000011d2: PUSH1 0x01 000011d4: ADD 000011d5: SWAP2 000011d6: SWAP1 000011d7: POP 000011d8: SSTORE 000011d9: POP 000011da: PUSH1 0x01 000011dc: SLOAD 000011dd: PUSH1 0x48 000011df: MUL 000011e0: TIMESTAMP 000011e1: ADD 000011e2: PUSH1 0x02 000011e4: PUSH1 0x04 000011e6: SLOAD 000011e7: DUP2 000011e8: SLOAD 000011e9: DUP2 000011ea: LT 000011eb: PUSH2 0x11f0 000011ee: JUMPI 000011ef: INVALID 000011f0: JUMPDEST 000011f1: SWAP1 000011f2: PUSH1 0x00 000011f4: MSTORE 000011f5: PUSH1 0x20 000011f7: PUSH1 0x00 000011f9: KECCAK256 000011fa: SWAP1 000011fb: PUSH1 0x07 000011fd: MUL 000011fe: ADD 000011ff: PUSH1 0x00 00001201: ADD 00001202: DUP2 00001203: SWAP1 00001204: SSTORE 00001205: POP 00001206: PUSH1 0x02 00001208: PUSH1 0x04 0000120a: SLOAD 0000120b: DUP2 0000120c: SLOAD 0000120d: DUP2 0000120e: LT 0000120f: PUSH2 0x1214 00001212: JUMPI 00001213: INVALID 00001214: JUMPDEST 00001215: SWAP1 00001216: PUSH1 0x00 00001218: MSTORE 00001219: PUSH1 0x20 0000121b: PUSH1 0x00 0000121d: KECCAK256 0000121e: SWAP1 0000121f: PUSH1 0x07 00001221: MUL 00001222: ADD 00001223: PUSH1 0x02 00001225: ADD 00001226: SLOAD 00001227: PUSH1 0x02 00001229: PUSH1 0x04 0000122b: SLOAD 0000122c: DUP2 0000122d: SLOAD 0000122e: DUP2 0000122f: LT 00001230: PUSH2 0x1235 00001233: JUMPI 00001234: INVALID 00001235: JUMPDEST 00001236: SWAP1 00001237: PUSH1 0x00 00001239: MSTORE 0000123a: PUSH1 0x20 0000123c: PUSH1 0x00 0000123e: KECCAK256 0000123f: SWAP1 00001240: PUSH1 0x07 00001242: MUL 00001243: ADD 00001244: PUSH1 0x00 00001246: ADD 00001247: SLOAD 00001248: ADD 00001249: PUSH1 0x02 0000124b: PUSH1 0x04 0000124d: SLOAD 0000124e: DUP2 0000124f: SLOAD 00001250: DUP2 00001251: LT 00001252: PUSH2 0x1257 00001255: JUMPI 00001256: INVALID 00001257: JUMPDEST 00001258: SWAP1 00001259: PUSH1 0x00 0000125b: MSTORE 0000125c: PUSH1 0x20 0000125e: PUSH1 0x00 00001260: KECCAK256 00001261: SWAP1 00001262: PUSH1 0x07 00001264: MUL 00001265: ADD 00001266: PUSH1 0x01 00001268: ADD 00001269: DUP2 0000126a: SWAP1 0000126b: SSTORE 0000126c: POP 0000126d: PUSH1 0x01 0000126f: PUSH1 0x04 00001271: SLOAD 00001272: GT 00001273: ISZERO 00001274: PUSH2 0x1307 00001277: JUMPI 00001278: PUSH1 0x03 0000127a: PUSH1 0x01 0000127c: PUSH1 0x04 0000127e: SLOAD 0000127f: SUB 00001280: DUP2 00001281: SLOAD 00001282: DUP2 00001283: LT 00001284: PUSH2 0x1289 00001287: JUMPI 00001288: INVALID 00001289: JUMPDEST 0000128a: SWAP1 0000128b: PUSH1 0x00 0000128d: MSTORE 0000128e: PUSH1 0x20 00001290: PUSH1 0x00 00001292: KECCAK256 00001293: SWAP1 00001294: PUSH1 0x02 00001296: MUL 00001297: ADD 00001298: PUSH1 0x00 0000129a: ADD 0000129b: SLOAD 0000129c: PUSH1 0x02 0000129e: PUSH1 0x01 000012a0: PUSH1 0x04 000012a2: SLOAD 000012a3: SUB 000012a4: DUP2 000012a5: SLOAD 000012a6: DUP2 000012a7: LT 000012a8: PUSH2 0x12ad 000012ab: JUMPI 000012ac: INVALID 000012ad: JUMPDEST 000012ae: SWAP1 000012af: PUSH1 0x00 000012b1: MSTORE 000012b2: PUSH1 0x20 000012b4: PUSH1 0x00 000012b6: KECCAK256 000012b7: SWAP1 000012b8: PUSH1 0x07 000012ba: MUL 000012bb: ADD 000012bc: PUSH1 0x03 000012be: ADD 000012bf: SLOAD 000012c0: PUSH1 0x02 000012c2: PUSH1 0x04 000012c4: SLOAD 000012c5: DUP2 000012c6: SLOAD 000012c7: DUP2 000012c8: LT 000012c9: PUSH2 0x12ce 000012cc: JUMPI 000012cd: INVALID 000012ce: JUMPDEST 000012cf: SWAP1 000012d0: PUSH1 0x00 000012d2: MSTORE 000012d3: PUSH1 0x20 000012d5: PUSH1 0x00 000012d7: KECCAK256 000012d8: SWAP1 000012d9: PUSH1 0x07 000012db: MUL 000012dc: ADD 000012dd: PUSH1 0x03 000012df: ADD 000012e0: SLOAD 000012e1: ADD 000012e2: SUB 000012e3: PUSH1 0x02 000012e5: PUSH1 0x04 000012e7: SLOAD 000012e8: DUP2 000012e9: SLOAD 000012ea: DUP2 000012eb: LT 000012ec: PUSH2 0x12f1 000012ef: JUMPI 000012f0: INVALID 000012f1: JUMPDEST 000012f2: SWAP1 000012f3: PUSH1 0x00 000012f5: MSTORE 000012f6: PUSH1 0x20 000012f8: PUSH1 0x00 000012fa: KECCAK256 000012fb: SWAP1 000012fc: PUSH1 0x07 000012fe: MUL 000012ff: ADD 00001300: PUSH1 0x03 00001302: ADD 00001303: DUP2 00001304: SWAP1 00001305: SSTORE 00001306: POP 00001307: JUMPDEST 00001308: PUSH2 0x0a8e 0000130b: JUMP 0000130c: JUMPDEST 0000130d: TIMESTAMP 0000130e: PUSH1 0x02 00001310: PUSH1 0x04 00001312: SLOAD 00001313: DUP2 00001314: SLOAD 00001315: DUP2 00001316: LT 00001317: PUSH2 0x131c 0000131a: JUMPI 0000131b: INVALID 0000131c: JUMPDEST 0000131d: SWAP1 0000131e: PUSH1 0x00 00001320: MSTORE 00001321: PUSH1 0x20 00001323: PUSH1 0x00 00001325: KECCAK256 00001326: SWAP1 00001327: PUSH1 0x07 00001329: MUL 0000132a: ADD 0000132b: PUSH1 0x01 0000132d: ADD 0000132e: SLOAD 0000132f: LT 00001330: DUP1 00001331: ISZERO 00001332: PUSH2 0x1344 00001335: JUMPI 00001336: POP 00001337: PUSH1 0x04 00001339: SLOAD 0000133a: PUSH1 0x01 0000133c: ADD 0000133d: PUSH1 0x02 0000133f: DUP1 00001340: SLOAD 00001341: SWAP1 00001342: POP 00001343: GT 00001344: JUMPDEST 00001345: DUP1 00001346: ISZERO 00001347: PUSH2 0x1390 0000134a: JUMPI 0000134b: POP 0000134c: PUSH1 0x03 0000134e: PUSH1 0x04 00001350: SLOAD 00001351: DUP2 00001352: SLOAD 00001353: DUP2 00001354: LT 00001355: PUSH2 0x135a 00001358: JUMPI 00001359: INVALID 0000135a: JUMPDEST 0000135b: SWAP1 0000135c: PUSH1 0x00 0000135e: MSTORE 0000135f: PUSH1 0x20 00001361: PUSH1 0x00 00001363: KECCAK256 00001364: SWAP1 00001365: PUSH1 0x02 00001367: MUL 00001368: ADD 00001369: PUSH1 0x00 0000136b: ADD 0000136c: SLOAD 0000136d: PUSH1 0x02 0000136f: PUSH1 0x04 00001371: SLOAD 00001372: DUP2 00001373: SLOAD 00001374: DUP2 00001375: LT 00001376: PUSH2 0x137b 00001379: JUMPI 0000137a: INVALID 0000137b: JUMPDEST 0000137c: SWAP1 0000137d: PUSH1 0x00 0000137f: MSTORE 00001380: PUSH1 0x20 00001382: PUSH1 0x00 00001384: KECCAK256 00001385: SWAP1 00001386: PUSH1 0x07 00001388: MUL 00001389: ADD 0000138a: PUSH1 0x03 0000138c: ADD 0000138d: SLOAD 0000138e: GT 0000138f: ISZERO 00001390: JUMPDEST 00001391: ISZERO 00001392: PUSH2 0x0a8e 00001395: JUMPI 00001396: PUSH1 0x04 00001398: PUSH1 0x00 0000139a: DUP2 0000139b: SLOAD 0000139c: DUP1 0000139d: SWAP3 0000139e: SWAP2 0000139f: SWAP1 000013a0: PUSH1 0x01 000013a2: ADD 000013a3: SWAP2 000013a4: SWAP1 000013a5: POP 000013a6: SSTORE 000013a7: POP 000013a8: PUSH1 0x01 000013aa: SLOAD 000013ab: PUSH1 0x0c 000013ad: MUL 000013ae: TIMESTAMP 000013af: ADD 000013b0: PUSH1 0x02 000013b2: PUSH1 0x04 000013b4: SLOAD 000013b5: DUP2 000013b6: SLOAD 000013b7: DUP2 000013b8: LT 000013b9: PUSH2 0x13be 000013bc: JUMPI 000013bd: INVALID 000013be: JUMPDEST 000013bf: SWAP1 000013c0: PUSH1 0x00 000013c2: MSTORE 000013c3: PUSH1 0x20 000013c5: PUSH1 0x00 000013c7: KECCAK256 000013c8: SWAP1 000013c9: PUSH1 0x07 000013cb: MUL 000013cc: ADD 000013cd: PUSH1 0x00 000013cf: ADD 000013d0: DUP2 000013d1: SWAP1 000013d2: SSTORE 000013d3: POP 000013d4: PUSH1 0x02 000013d6: PUSH1 0x04 000013d8: SLOAD 000013d9: DUP2 000013da: SLOAD 000013db: DUP2 000013dc: LT 000013dd: PUSH2 0x13e2 000013e0: JUMPI 000013e1: INVALID 000013e2: JUMPDEST 000013e3: SWAP1 000013e4: PUSH1 0x00 000013e6: MSTORE 000013e7: PUSH1 0x20 000013e9: PUSH1 0x00 000013eb: KECCAK256 000013ec: SWAP1 000013ed: PUSH1 0x07 000013ef: MUL 000013f0: ADD 000013f1: PUSH1 0x02 000013f3: ADD 000013f4: SLOAD 000013f5: PUSH1 0x02 000013f7: PUSH1 0x04 000013f9: SLOAD 000013fa: DUP2 000013fb: SLOAD 000013fc: DUP2 000013fd: LT 000013fe: PUSH2 0x1403 00001401: JUMPI 00001402: INVALID 00001403: JUMPDEST 00001404: SWAP1 00001405: PUSH1 0x00 00001407: MSTORE 00001408: PUSH1 0x20 0000140a: PUSH1 0x00 0000140c: KECCAK256 0000140d: SWAP1 0000140e: PUSH1 0x07 00001410: MUL 00001411: ADD 00001412: PUSH1 0x00 00001414: ADD 00001415: SLOAD 00001416: ADD 00001417: PUSH1 0x02 00001419: PUSH1 0x04 0000141b: SLOAD 0000141c: DUP2 0000141d: SLOAD 0000141e: DUP2 0000141f: LT 00001420: PUSH2 0x1425 00001423: JUMPI 00001424: INVALID 00001425: JUMPDEST 00001426: SWAP1 00001427: PUSH1 0x00 00001429: MSTORE 0000142a: PUSH1 0x20 0000142c: PUSH1 0x00 0000142e: KECCAK256 0000142f: SWAP1 00001430: PUSH1 0x07 00001432: MUL 00001433: ADD 00001434: PUSH1 0x01 00001436: ADD 00001437: DUP2 00001438: SWAP1 00001439: SSTORE 0000143a: POP 0000143b: POP 0000143c: JUMP 0000143d: JUMPDEST 0000143e: PUSH1 0x02 00001440: PUSH1 0x04 00001442: SLOAD 00001443: DUP2 00001444: SLOAD 00001445: DUP2 00001446: LT 00001447: PUSH2 0x144c 0000144a: JUMPI 0000144b: INVALID 0000144c: JUMPDEST 0000144d: SWAP1 0000144e: PUSH1 0x00 00001450: MSTORE 00001451: PUSH1 0x20 00001453: PUSH1 0x00 00001455: KECCAK256 00001456: SWAP1 00001457: PUSH1 0x07 00001459: MUL 0000145a: ADD 0000145b: PUSH1 0x01 0000145d: ADD 0000145e: SLOAD 0000145f: TIMESTAMP 00001460: GT 00001461: ISZERO 00001462: PUSH2 0x14b5 00001465: JUMPI 00001466: PUSH1 0x40 00001468: DUP1 00001469: MLOAD 0000146a: PUSH1 0x01 0000146c: PUSH1 0xe5 0000146e: SHL 0000146f: PUSH3 0x461bcd 00001473: MUL 00001474: DUP2 00001475: MSTORE 00001476: PUSH1 0x20 00001478: PUSH1 0x04 0000147a: DUP3 0000147b: ADD 0000147c: MSTORE 0000147d: PUSH1 0x1e 0000147f: PUSH1 0x24 00001481: DUP3 00001482: ADD 00001483: MSTORE 00001484: PUSH32 0x47484343726f7764616c653a2063726f776473616c652073746f707065640000 000014a5: PUSH1 0x44 000014a7: DUP3 000014a8: ADD 000014a9: MSTORE 000014aa: SWAP1 000014ab: MLOAD 000014ac: SWAP1 000014ad: DUP2 000014ae: SWAP1 000014af: SUB 000014b0: PUSH1 0x64 000014b2: ADD 000014b3: SWAP1 000014b4: REVERT 000014b5: JUMPDEST 000014b6: PUSH1 0x02 000014b8: PUSH1 0x04 000014ba: SLOAD 000014bb: DUP2 000014bc: SLOAD 000014bd: DUP2 000014be: LT 000014bf: PUSH2 0x14c4 000014c2: JUMPI 000014c3: INVALID 000014c4: JUMPDEST 000014c5: SWAP1 000014c6: PUSH1 0x00 000014c8: MSTORE 000014c9: PUSH1 0x20 000014cb: PUSH1 0x00 000014cd: KECCAK256 000014ce: SWAP1 000014cf: PUSH1 0x07 000014d1: MUL 000014d2: ADD 000014d3: PUSH1 0x00 000014d5: ADD 000014d6: SLOAD 000014d7: TIMESTAMP 000014d8: LT 000014d9: ISZERO 000014da: PUSH2 0x1517 000014dd: JUMPI 000014de: PUSH1 0x40 000014e0: MLOAD 000014e1: PUSH1 0x01 000014e3: PUSH1 0xe5 000014e5: SHL 000014e6: PUSH3 0x461bcd 000014ea: MUL 000014eb: DUP2 000014ec: MSTORE 000014ed: PUSH1 0x04 000014ef: ADD 000014f0: DUP1 000014f1: DUP1 000014f2: PUSH1 0x20 000014f4: ADD 000014f5: DUP3 000014f6: DUP2 000014f7: SUB 000014f8: DUP3 000014f9: MSTORE 000014fa: PUSH1 0x22 000014fc: DUP2 000014fd: MSTORE 000014fe: PUSH1 0x20 00001500: ADD 00001501: DUP1 00001502: PUSH2 0x21e0 00001505: PUSH1 0x22 00001507: SWAP2 00001508: CODECOPY 00001509: PUSH1 0x40 0000150b: ADD 0000150c: SWAP2 0000150d: POP 0000150e: POP 0000150f: PUSH1 0x40 00001511: MLOAD 00001512: DUP1 00001513: SWAP2 00001514: SUB 00001515: SWAP1 00001516: REVERT 00001517: JUMPDEST 00001518: PUSH1 0x02 0000151a: PUSH1 0x04 0000151c: SLOAD 0000151d: DUP2 0000151e: SLOAD 0000151f: DUP2 00001520: LT 00001521: PUSH2 0x1526 00001524: JUMPI 00001525: INVALID 00001526: JUMPDEST 00001527: SWAP1 00001528: PUSH1 0x00 0000152a: MSTORE 0000152b: PUSH1 0x20 0000152d: PUSH1 0x00 0000152f: KECCAK256 00001530: SWAP1 00001531: PUSH1 0x07 00001533: MUL 00001534: ADD 00001535: PUSH1 0x03 00001537: ADD 00001538: SLOAD 00001539: DUP2 0000153a: PUSH1 0x03 0000153c: PUSH1 0x04 0000153e: SLOAD 0000153f: DUP2 00001540: SLOAD 00001541: DUP2 00001542: LT 00001543: PUSH2 0x1548 00001546: JUMPI 00001547: INVALID 00001548: JUMPDEST 00001549: SWAP1 0000154a: PUSH1 0x00 0000154c: MSTORE 0000154d: PUSH1 0x20 0000154f: PUSH1 0x00 00001551: KECCAK256 00001552: SWAP1 00001553: PUSH1 0x02 00001555: MUL 00001556: ADD 00001557: PUSH1 0x00 00001559: ADD 0000155a: SLOAD 0000155b: ADD 0000155c: GT 0000155d: ISZERO 0000155e: PUSH2 0x159b 00001561: JUMPI 00001562: PUSH1 0x40 00001564: MLOAD 00001565: PUSH1 0x01 00001567: PUSH1 0xe5 00001569: SHL 0000156a: PUSH3 0x461bcd 0000156e: MUL 0000156f: DUP2 00001570: MSTORE 00001571: PUSH1 0x04 00001573: ADD 00001574: DUP1 00001575: DUP1 00001576: PUSH1 0x20 00001578: ADD 00001579: DUP3 0000157a: DUP2 0000157b: SUB 0000157c: DUP3 0000157d: MSTORE 0000157e: PUSH1 0x21 00001580: DUP2 00001581: MSTORE 00001582: PUSH1 0x20 00001584: ADD 00001585: DUP1 00001586: PUSH2 0x2202 00001589: PUSH1 0x21 0000158b: SWAP2 0000158c: CODECOPY 0000158d: PUSH1 0x40 0000158f: ADD 00001590: SWAP2 00001591: POP 00001592: POP 00001593: PUSH1 0x40 00001595: MLOAD 00001596: DUP1 00001597: SWAP2 00001598: SUB 00001599: SWAP1 0000159a: REVERT 0000159b: JUMPDEST 0000159c: PUSH1 0x02 0000159e: PUSH1 0x04 000015a0: SLOAD 000015a1: DUP2 000015a2: SLOAD 000015a3: DUP2 000015a4: LT 000015a5: PUSH2 0x15aa 000015a8: JUMPI 000015a9: INVALID 000015aa: JUMPDEST 000015ab: SWAP1 000015ac: PUSH1 0x00 000015ae: MSTORE 000015af: PUSH1 0x20 000015b1: PUSH1 0x00 000015b3: KECCAK256 000015b4: SWAP1 000015b5: PUSH1 0x07 000015b7: MUL 000015b8: ADD 000015b9: PUSH1 0x05 000015bb: ADD 000015bc: SLOAD 000015bd: DUP2 000015be: PUSH1 0x03 000015c0: PUSH1 0x04 000015c2: SLOAD 000015c3: DUP2 000015c4: SLOAD 000015c5: DUP2 000015c6: LT 000015c7: PUSH2 0x15cc 000015ca: JUMPI 000015cb: INVALID 000015cc: JUMPDEST 000015cd: PUSH1 0x00 000015cf: SWAP2 000015d0: DUP3 000015d1: MSTORE 000015d2: PUSH1 0x20 000015d4: DUP1 000015d5: DUP4 000015d6: KECCAK256 000015d7: PUSH1 0x01 000015d9: PUSH1 0x01 000015db: PUSH1 0xa0 000015dd: SHL 000015de: SUB 000015df: DUP9 000015e0: AND 000015e1: DUP5 000015e2: MSTORE 000015e3: PUSH1 0x01 000015e5: PUSH1 0x02 000015e7: SWAP1 000015e8: SWAP4 000015e9: MUL 000015ea: ADD 000015eb: SWAP2 000015ec: SWAP1 000015ed: SWAP2 000015ee: ADD 000015ef: SWAP1 000015f0: MSTORE 000015f1: PUSH1 0x40 000015f3: SWAP1 000015f4: KECCAK256 000015f5: SLOAD 000015f6: ADD 000015f7: GT 000015f8: ISZERO 000015f9: PUSH2 0x1636 000015fc: JUMPI 000015fd: PUSH1 0x40 000015ff: MLOAD 00001600: PUSH1 0x01 00001602: PUSH1 0xe5 00001604: SHL 00001605: PUSH3 0x461bcd 00001609: MUL 0000160a: DUP2 0000160b: MSTORE 0000160c: PUSH1 0x04 0000160e: ADD 0000160f: DUP1 00001610: DUP1 00001611: PUSH1 0x20 00001613: ADD 00001614: DUP3 00001615: DUP2 00001616: SUB 00001617: DUP3 00001618: MSTORE 00001619: PUSH1 0x29 0000161b: DUP2 0000161c: MSTORE 0000161d: PUSH1 0x20 0000161f: ADD 00001620: DUP1 00001621: PUSH2 0x2244 00001624: PUSH1 0x29 00001626: SWAP2 00001627: CODECOPY 00001628: PUSH1 0x40 0000162a: ADD 0000162b: SWAP2 0000162c: POP 0000162d: POP 0000162e: PUSH1 0x40 00001630: MLOAD 00001631: DUP1 00001632: SWAP2 00001633: SUB 00001634: SWAP1 00001635: REVERT 00001636: JUMPDEST 00001637: PUSH1 0x02 00001639: PUSH1 0x04 0000163b: SLOAD 0000163c: DUP2 0000163d: SLOAD 0000163e: DUP2 0000163f: LT 00001640: PUSH2 0x1645 00001643: JUMPI 00001644: INVALID 00001645: JUMPDEST 00001646: SWAP1 00001647: PUSH1 0x00 00001649: MSTORE 0000164a: PUSH1 0x20 0000164c: PUSH1 0x00 0000164e: KECCAK256 0000164f: SWAP1 00001650: PUSH1 0x07 00001652: MUL 00001653: ADD 00001654: PUSH1 0x06 00001656: ADD 00001657: SLOAD 00001658: DUP2 00001659: LT 0000165a: ISZERO 0000165b: PUSH2 0x1698 0000165e: JUMPI 0000165f: PUSH1 0x40 00001661: MLOAD 00001662: PUSH1 0x01 00001664: PUSH1 0xe5 00001666: SHL 00001667: PUSH3 0x461bcd 0000166b: MUL 0000166c: DUP2 0000166d: MSTORE 0000166e: PUSH1 0x04 00001670: ADD 00001671: DUP1 00001672: DUP1 00001673: PUSH1 0x20 00001675: ADD 00001676: DUP3 00001677: DUP2 00001678: SUB 00001679: DUP3 0000167a: MSTORE 0000167b: PUSH1 0x29 0000167d: DUP2 0000167e: MSTORE 0000167f: PUSH1 0x20 00001681: ADD 00001682: DUP1 00001683: PUSH2 0x2244 00001686: PUSH1 0x29 00001688: SWAP2 00001689: CODECOPY 0000168a: PUSH1 0x40 0000168c: ADD 0000168d: SWAP2 0000168e: POP 0000168f: POP 00001690: PUSH1 0x40 00001692: MLOAD 00001693: DUP1 00001694: SWAP2 00001695: SUB 00001696: SWAP1 00001697: REVERT 00001698: JUMPDEST 00001699: POP 0000169a: POP 0000169b: JUMP 0000169c: JUMPDEST 0000169d: PUSH1 0x0e 0000169f: SLOAD 000016a0: PUSH1 0xff 000016a2: AND 000016a3: ISZERO 000016a4: PUSH2 0x16ed 000016a7: JUMPI 000016a8: PUSH1 0x40 000016aa: DUP1 000016ab: MLOAD 000016ac: PUSH1 0x01 000016ae: PUSH1 0xe5 000016b0: SHL 000016b1: PUSH3 0x461bcd 000016b5: MUL 000016b6: DUP2 000016b7: MSTORE 000016b8: PUSH1 0x20 000016ba: PUSH1 0x04 000016bc: DUP3 000016bd: ADD 000016be: MSTORE 000016bf: PUSH1 0x10 000016c1: PUSH1 0x24 000016c3: DUP3 000016c4: ADD 000016c5: MSTORE 000016c6: PUSH1 0x01 000016c8: PUSH1 0x82 000016ca: SHL 000016cb: PUSH16 0x14185d5cd8589b194e881c185d5cd959 000016dc: MUL 000016dd: PUSH1 0x44 000016df: DUP3 000016e0: ADD 000016e1: MSTORE 000016e2: SWAP1 000016e3: MLOAD 000016e4: SWAP1 000016e5: DUP2 000016e6: SWAP1 000016e7: SUB 000016e8: PUSH1 0x64 000016ea: ADD 000016eb: SWAP1 000016ec: REVERT 000016ed: JUMPDEST 000016ee: PUSH2 0x1698 000016f1: DUP3 000016f2: DUP3 000016f3: PUSH2 0x1b57 000016f6: JUMP 000016f7: JUMPDEST 000016f8: PUSH1 0x00 000016fa: PUSH2 0x083e 000016fd: PUSH1 0x02 000016ff: PUSH1 0x04 00001701: SLOAD 00001702: DUP2 00001703: SLOAD 00001704: DUP2 00001705: LT 00001706: PUSH2 0x170b 00001709: JUMPI 0000170a: INVALID 0000170b: JUMPDEST 0000170c: SWAP1 0000170d: PUSH1 0x00 0000170f: MSTORE 00001710: PUSH1 0x20 00001712: PUSH1 0x00 00001714: KECCAK256 00001715: SWAP1 00001716: PUSH1 0x07 00001718: MUL 00001719: ADD 0000171a: PUSH1 0x04 0000171c: ADD 0000171d: SLOAD 0000171e: DUP4 0000171f: PUSH2 0x1bf4 00001722: SWAP1 00001723: SWAP2 00001724: SWAP1 00001725: PUSH4 0xffffffff 0000172a: AND 0000172b: JUMP 0000172c: JUMPDEST 0000172d: PUSH1 0x00 0000172f: DUP3 00001730: DUP3 00001731: ADD 00001732: DUP4 00001733: DUP2 00001734: LT 00001735: ISZERO 00001736: PUSH2 0x1789 00001739: JUMPI 0000173a: PUSH1 0x40 0000173c: DUP1 0000173d: MLOAD 0000173e: PUSH1 0x01 00001740: PUSH1 0xe5 00001742: SHL 00001743: PUSH3 0x461bcd 00001747: MUL 00001748: DUP2 00001749: MSTORE 0000174a: PUSH1 0x20 0000174c: PUSH1 0x04 0000174e: DUP3 0000174f: ADD 00001750: MSTORE 00001751: PUSH1 0x1b 00001753: PUSH1 0x24 00001755: DUP3 00001756: ADD 00001757: MSTORE 00001758: PUSH32 0x536166654d6174683a206164646974696f6e206f766572666c6f770000000000 00001779: PUSH1 0x44 0000177b: DUP3 0000177c: ADD 0000177d: MSTORE 0000177e: SWAP1 0000177f: MLOAD 00001780: SWAP1 00001781: DUP2 00001782: SWAP1 00001783: SUB 00001784: PUSH1 0x64 00001786: ADD 00001787: SWAP1 00001788: REVERT 00001789: JUMPDEST 0000178a: SWAP4 0000178b: SWAP3 0000178c: POP 0000178d: POP 0000178e: POP 0000178f: JUMP 00001790: JUMPDEST 00001791: PUSH2 0x1698 00001794: DUP3 00001795: DUP3 00001796: PUSH2 0x1c50 00001799: JUMP 0000179a: JUMPDEST 0000179b: PUSH1 0x00 0000179d: PUSH2 0x17b3 000017a0: PUSH1 0x07 000017a2: SLOAD 000017a3: PUSH1 0x06 000017a5: SLOAD 000017a6: PUSH2 0x1c6d 000017a9: SWAP1 000017aa: SWAP2 000017ab: SWAP1 000017ac: PUSH4 0xffffffff 000017b1: AND 000017b2: JUMP 000017b3: JUMPDEST 000017b4: SWAP1 000017b5: POP 000017b6: PUSH1 0x0b 000017b8: SLOAD 000017b9: DUP2 000017ba: LT 000017bb: PUSH2 0x0a8e 000017be: JUMPI 000017bf: PUSH1 0x08 000017c1: SLOAD 000017c2: PUSH1 0x01 000017c4: PUSH1 0x01 000017c6: PUSH1 0xa0 000017c8: SHL 000017c9: SUB 000017ca: AND 000017cb: PUSH1 0x00 000017cd: SWAP1 000017ce: DUP2 000017cf: MSTORE 000017d0: PUSH1 0x0c 000017d2: PUSH1 0x20 000017d4: MSTORE 000017d5: PUSH1 0x40 000017d7: DUP2 000017d8: KECCAK256 000017d9: SLOAD 000017da: PUSH2 0x17fc 000017dd: SWAP1 000017de: PUSH1 0x64 000017e0: SWAP1 000017e1: PUSH2 0x17f0 000017e4: SWAP1 000017e5: DUP6 000017e6: PUSH4 0xffffffff 000017eb: PUSH2 0x1bf4 000017ee: AND 000017ef: JUMP 000017f0: JUMPDEST 000017f1: SWAP1 000017f2: PUSH4 0xffffffff 000017f7: PUSH2 0x1caf 000017fa: AND 000017fb: JUMP 000017fc: JUMPDEST 000017fd: SWAP1 000017fe: POP 000017ff: DUP1 00001800: ISZERO 00001801: PUSH2 0x1840 00001804: JUMPI 00001805: PUSH1 0x08 00001807: SLOAD 00001808: PUSH1 0x40 0000180a: MLOAD 0000180b: PUSH1 0x01 0000180d: PUSH1 0x01 0000180f: PUSH1 0xa0 00001811: SHL 00001812: SUB 00001813: SWAP1 00001814: SWAP2 00001815: AND 00001816: SWAP1 00001817: DUP3 00001818: ISZERO 00001819: PUSH2 0x08fc 0000181c: MUL 0000181d: SWAP1 0000181e: DUP4 0000181f: SWAP1 00001820: PUSH1 0x00 00001822: DUP2 00001823: DUP2 00001824: DUP2 00001825: DUP6 00001826: DUP9 00001827: DUP9 00001828: CALL 00001829: SWAP4 0000182a: POP 0000182b: POP 0000182c: POP 0000182d: POP 0000182e: ISZERO 0000182f: DUP1 00001830: ISZERO 00001831: PUSH2 0x183e 00001834: JUMPI 00001835: RETURNDATASIZE 00001836: PUSH1 0x00 00001838: DUP1 00001839: RETURNDATACOPY 0000183a: RETURNDATASIZE 0000183b: PUSH1 0x00 0000183d: REVERT 0000183e: JUMPDEST 0000183f: POP 00001840: JUMPDEST 00001841: PUSH1 0x09 00001843: SLOAD 00001844: PUSH1 0x01 00001846: PUSH1 0x01 00001848: PUSH1 0xa0 0000184a: SHL 0000184b: SUB 0000184c: AND 0000184d: PUSH1 0x00 0000184f: SWAP1 00001850: DUP2 00001851: MSTORE 00001852: PUSH1 0x0c 00001854: PUSH1 0x20 00001856: MSTORE 00001857: PUSH1 0x40 00001859: DUP2 0000185a: KECCAK256 0000185b: SLOAD 0000185c: PUSH2 0x1872 0000185f: SWAP1 00001860: PUSH1 0x64 00001862: SWAP1 00001863: PUSH2 0x17f0 00001866: SWAP1 00001867: DUP7 00001868: PUSH4 0xffffffff 0000186d: PUSH2 0x1bf4 00001870: AND 00001871: JUMP 00001872: JUMPDEST 00001873: SWAP1 00001874: POP 00001875: DUP1 00001876: ISZERO 00001877: PUSH2 0x18b6 0000187a: JUMPI 0000187b: PUSH1 0x09 0000187d: SLOAD 0000187e: PUSH1 0x40 00001880: MLOAD 00001881: PUSH1 0x01 00001883: PUSH1 0x01 00001885: PUSH1 0xa0 00001887: SHL 00001888: SUB 00001889: SWAP1 0000188a: SWAP2 0000188b: AND 0000188c: SWAP1 0000188d: DUP3 0000188e: ISZERO 0000188f: PUSH2 0x08fc 00001892: MUL 00001893: SWAP1 00001894: DUP4 00001895: SWAP1 00001896: PUSH1 0x00 00001898: DUP2 00001899: DUP2 0000189a: DUP2 0000189b: DUP6 0000189c: DUP9 0000189d: DUP9 0000189e: CALL 0000189f: SWAP4 000018a0: POP 000018a1: POP 000018a2: POP 000018a3: POP 000018a4: ISZERO 000018a5: DUP1 000018a6: ISZERO 000018a7: PUSH2 0x18b4 000018aa: JUMPI 000018ab: RETURNDATASIZE 000018ac: PUSH1 0x00 000018ae: DUP1 000018af: RETURNDATACOPY 000018b0: RETURNDATASIZE 000018b1: PUSH1 0x00 000018b3: REVERT 000018b4: JUMPDEST 000018b5: POP 000018b6: JUMPDEST 000018b7: PUSH1 0x0a 000018b9: SLOAD 000018ba: PUSH1 0x01 000018bc: PUSH1 0x01 000018be: PUSH1 0xa0 000018c0: SHL 000018c1: SUB 000018c2: AND 000018c3: PUSH1 0x00 000018c5: SWAP1 000018c6: DUP2 000018c7: MSTORE 000018c8: PUSH1 0x0c 000018ca: PUSH1 0x20 000018cc: MSTORE 000018cd: PUSH1 0x40 000018cf: DUP2 000018d0: KECCAK256 000018d1: SLOAD 000018d2: PUSH2 0x18e8 000018d5: SWAP1 000018d6: PUSH1 0x64 000018d8: SWAP1 000018d9: PUSH2 0x17f0 000018dc: SWAP1 000018dd: DUP8 000018de: PUSH4 0xffffffff 000018e3: PUSH2 0x1bf4 000018e6: AND 000018e7: JUMP 000018e8: JUMPDEST 000018e9: SWAP1 000018ea: POP 000018eb: DUP1 000018ec: ISZERO 000018ed: PUSH2 0x192c 000018f0: JUMPI 000018f1: PUSH1 0x0a 000018f3: SLOAD 000018f4: PUSH1 0x40 000018f6: MLOAD 000018f7: PUSH1 0x01 000018f9: PUSH1 0x01 000018fb: PUSH1 0xa0 000018fd: SHL 000018fe: SUB 000018ff: SWAP1 00001900: SWAP2 00001901: AND 00001902: SWAP1 00001903: DUP3 00001904: ISZERO 00001905: PUSH2 0x08fc 00001908: MUL 00001909: SWAP1 0000190a: DUP4 0000190b: SWAP1 0000190c: PUSH1 0x00 0000190e: DUP2 0000190f: DUP2 00001910: DUP2 00001911: DUP6 00001912: DUP9 00001913: DUP9 00001914: CALL 00001915: SWAP4 00001916: POP 00001917: POP 00001918: POP 00001919: POP 0000191a: ISZERO 0000191b: DUP1 0000191c: ISZERO 0000191d: PUSH2 0x192a 00001920: JUMPI 00001921: RETURNDATASIZE 00001922: PUSH1 0x00 00001924: DUP1 00001925: RETURNDATACOPY 00001926: RETURNDATASIZE 00001927: PUSH1 0x00 00001929: REVERT 0000192a: JUMPDEST 0000192b: POP 0000192c: JUMPDEST 0000192d: PUSH1 0x07 0000192f: SLOAD 00001930: PUSH2 0x193f 00001933: SWAP1 00001934: DUP6 00001935: PUSH4 0xffffffff 0000193a: PUSH2 0x172c 0000193d: AND 0000193e: JUMP 0000193f: JUMPDEST 00001940: POP 00001941: PUSH1 0x08 00001943: SLOAD 00001944: PUSH1 0x09 00001946: SLOAD 00001947: PUSH1 0x0a 00001949: SLOAD 0000194a: PUSH1 0x40 0000194c: DUP1 0000194d: MLOAD 0000194e: PUSH1 0x01 00001950: PUSH1 0x01 00001952: PUSH1 0xa0 00001954: SHL 00001955: SUB 00001956: SWAP5 00001957: DUP6 00001958: AND 00001959: DUP2 0000195a: MSTORE 0000195b: PUSH1 0x20 0000195d: DUP2 0000195e: ADD 0000195f: DUP9 00001960: SWAP1 00001961: MSTORE 00001962: SWAP3 00001963: DUP5 00001964: AND 00001965: DUP4 00001966: DUP3 00001967: ADD 00001968: MSTORE 00001969: PUSH1 0x60 0000196b: DUP4 0000196c: ADD 0000196d: DUP7 0000196e: SWAP1 0000196f: MSTORE 00001970: SWAP3 00001971: AND 00001972: PUSH1 0x80 00001974: DUP3 00001975: ADD 00001976: MSTORE 00001977: PUSH1 0xa0 00001979: DUP2 0000197a: ADD 0000197b: DUP4 0000197c: SWAP1 0000197d: MSTORE 0000197e: SWAP1 0000197f: MLOAD 00001980: PUSH32 0x58b7c4c18cf39abd52d5d3a43069adf153de65905e011949dc05cb3a9d6611c2 000019a1: SWAP2 000019a2: DUP2 000019a3: SWAP1 000019a4: SUB 000019a5: PUSH1 0xc0 000019a7: ADD 000019a8: SWAP1 000019a9: LOG1 000019aa: POP 000019ab: POP 000019ac: POP 000019ad: POP 000019ae: JUMP 000019af: JUMPDEST 000019b0: PUSH1 0x00 000019b2: PUSH1 0x01 000019b4: PUSH1 0x01 000019b6: PUSH1 0xa0 000019b8: SHL 000019b9: SUB 000019ba: DUP3 000019bb: AND 000019bc: PUSH2 0x19f9 000019bf: JUMPI 000019c0: PUSH1 0x40 000019c2: MLOAD 000019c3: PUSH1 0x01 000019c5: PUSH1 0xe5 000019c7: SHL 000019c8: PUSH3 0x461bcd 000019cc: MUL 000019cd: DUP2 000019ce: MSTORE 000019cf: PUSH1 0x04 000019d1: ADD 000019d2: DUP1 000019d3: DUP1 000019d4: PUSH1 0x20 000019d6: ADD 000019d7: DUP3 000019d8: DUP2 000019d9: SUB 000019da: DUP3 000019db: MSTORE 000019dc: PUSH1 0x22 000019de: DUP2 000019df: MSTORE 000019e0: PUSH1 0x20 000019e2: ADD 000019e3: DUP1 000019e4: PUSH2 0x22ae 000019e7: PUSH1 0x22 000019e9: SWAP2 000019ea: CODECOPY 000019eb: PUSH1 0x40 000019ed: ADD 000019ee: SWAP2 000019ef: POP 000019f0: POP 000019f1: PUSH1 0x40 000019f3: MLOAD 000019f4: DUP1 000019f5: SWAP2 000019f6: SUB 000019f7: SWAP1 000019f8: REVERT 000019f9: JUMPDEST 000019fa: POP 000019fb: PUSH1 0x01 000019fd: PUSH1 0x01 000019ff: PUSH1 0xa0 00001a01: SHL 00001a02: SUB 00001a03: AND 00001a04: PUSH1 0x00 00001a06: SWAP1 00001a07: DUP2 00001a08: MSTORE 00001a09: PUSH1 0x20 00001a0b: SWAP2 00001a0c: SWAP1 00001a0d: SWAP2 00001a0e: MSTORE 00001a0f: PUSH1 0x40 00001a11: SWAP1 00001a12: KECCAK256 00001a13: SLOAD 00001a14: PUSH1 0xff 00001a16: AND 00001a17: SWAP1 00001a18: JUMP 00001a19: JUMPDEST 00001a1a: PUSH2 0x1a2a 00001a1d: PUSH1 0x0d 00001a1f: DUP3 00001a20: PUSH4 0xffffffff 00001a25: PUSH2 0x1cf1 00001a28: AND 00001a29: JUMP 00001a2a: JUMPDEST 00001a2b: PUSH1 0x40 00001a2d: MLOAD 00001a2e: PUSH1 0x01 00001a30: PUSH1 0x01 00001a32: PUSH1 0xa0 00001a34: SHL 00001a35: SUB 00001a36: DUP3 00001a37: AND 00001a38: SWAP1 00001a39: PUSH32 0xcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e 00001a5a: SWAP1 00001a5b: PUSH1 0x00 00001a5d: SWAP1 00001a5e: LOG2 00001a5f: POP 00001a60: JUMP 00001a61: JUMPDEST 00001a62: PUSH2 0x1a72 00001a65: PUSH1 0x0d 00001a67: DUP3 00001a68: PUSH4 0xffffffff 00001a6d: PUSH2 0x1d5b 00001a70: AND 00001a71: JUMP 00001a72: JUMPDEST 00001a73: PUSH1 0x40 00001a75: MLOAD 00001a76: PUSH1 0x01 00001a78: PUSH1 0x01 00001a7a: PUSH1 0xa0 00001a7c: SHL 00001a7d: SUB 00001a7e: DUP3 00001a7f: AND 00001a80: SWAP1 00001a81: PUSH32 0x6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f8 00001aa2: SWAP1 00001aa3: PUSH1 0x00 00001aa5: SWAP1 00001aa6: LOG2 00001aa7: POP 00001aa8: JUMP 00001aa9: JUMPDEST 00001aaa: PUSH1 0x01 00001aac: PUSH1 0x01 00001aae: PUSH1 0xa0 00001ab0: SHL 00001ab1: SUB 00001ab2: DUP2 00001ab3: AND 00001ab4: PUSH2 0x1af1 00001ab7: JUMPI 00001ab8: PUSH1 0x40 00001aba: MLOAD 00001abb: PUSH1 0x01 00001abd: PUSH1 0xe5 00001abf: SHL 00001ac0: PUSH3 0x461bcd 00001ac4: MUL 00001ac5: DUP2 00001ac6: MSTORE 00001ac7: PUSH1 0x04 00001ac9: ADD 00001aca: DUP1 00001acb: DUP1 00001acc: PUSH1 0x20 00001ace: ADD 00001acf: DUP3 00001ad0: DUP2 00001ad1: SUB 00001ad2: DUP3 00001ad3: MSTORE 00001ad4: PUSH1 0x26 00001ad6: DUP2 00001ad7: MSTORE 00001ad8: PUSH1 0x20 00001ada: ADD 00001adb: DUP1 00001adc: PUSH2 0x21ba 00001adf: PUSH1 0x26 00001ae1: SWAP2 00001ae2: CODECOPY 00001ae3: PUSH1 0x40 00001ae5: ADD 00001ae6: SWAP2 00001ae7: POP 00001ae8: POP 00001ae9: PUSH1 0x40 00001aeb: MLOAD 00001aec: DUP1 00001aed: SWAP2 00001aee: SUB 00001aef: SWAP1 00001af0: REVERT 00001af1: JUMPDEST 00001af2: PUSH1 0x00 00001af4: DUP1 00001af5: SLOAD 00001af6: PUSH1 0x40 00001af8: MLOAD 00001af9: PUSH1 0x01 00001afb: PUSH1 0x01 00001afd: PUSH1 0xa0 00001aff: SHL 00001b00: SUB 00001b01: DUP1 00001b02: DUP6 00001b03: AND 00001b04: SWAP4 00001b05: PUSH2 0x0100 00001b08: SWAP1 00001b09: SWAP4 00001b0a: DIV 00001b0b: AND 00001b0c: SWAP2 00001b0d: PUSH32 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0 00001b2e: SWAP2 00001b2f: LOG3 00001b30: PUSH1 0x00 00001b32: DUP1 00001b33: SLOAD 00001b34: PUSH1 0x01 00001b36: PUSH1 0x01 00001b38: PUSH1 0xa0 00001b3a: SHL 00001b3b: SUB 00001b3c: SWAP1 00001b3d: SWAP3 00001b3e: AND 00001b3f: PUSH2 0x0100 00001b42: MUL 00001b43: PUSH2 0x0100 00001b46: PUSH1 0x01 00001b48: PUSH1 0xa8 00001b4a: SHL 00001b4b: SUB 00001b4c: NOT 00001b4d: SWAP1 00001b4e: SWAP3 00001b4f: AND 00001b50: SWAP2 00001b51: SWAP1 00001b52: SWAP2 00001b53: OR 00001b54: SWAP1 00001b55: SSTORE 00001b56: JUMP 00001b57: JUMPDEST 00001b58: PUSH1 0x01 00001b5a: PUSH1 0x01 00001b5c: PUSH1 0xa0 00001b5e: SHL 00001b5f: SUB 00001b60: DUP3 00001b61: AND 00001b62: PUSH2 0x1b9f 00001b65: JUMPI 00001b66: PUSH1 0x40 00001b68: MLOAD 00001b69: PUSH1 0x01 00001b6b: PUSH1 0xe5 00001b6d: SHL 00001b6e: PUSH3 0x461bcd 00001b72: MUL 00001b73: DUP2 00001b74: MSTORE 00001b75: PUSH1 0x04 00001b77: ADD 00001b78: DUP1 00001b79: DUP1 00001b7a: PUSH1 0x20 00001b7c: ADD 00001b7d: DUP3 00001b7e: DUP2 00001b7f: SUB 00001b80: DUP3 00001b81: MSTORE 00001b82: PUSH1 0x2a 00001b84: DUP2 00001b85: MSTORE 00001b86: PUSH1 0x20 00001b88: ADD 00001b89: DUP1 00001b8a: PUSH2 0x22d0 00001b8d: PUSH1 0x2a 00001b8f: SWAP2 00001b90: CODECOPY 00001b91: PUSH1 0x40 00001b93: ADD 00001b94: SWAP2 00001b95: POP 00001b96: POP 00001b97: PUSH1 0x40 00001b99: MLOAD 00001b9a: DUP1 00001b9b: SWAP2 00001b9c: SUB 00001b9d: SWAP1 00001b9e: REVERT 00001b9f: JUMPDEST 00001ba0: DUP1 00001ba1: PUSH2 0x1698 00001ba4: JUMPI 00001ba5: PUSH1 0x40 00001ba7: DUP1 00001ba8: MLOAD 00001ba9: PUSH1 0x01 00001bab: PUSH1 0xe5 00001bad: SHL 00001bae: PUSH3 0x461bcd 00001bb2: MUL 00001bb3: DUP2 00001bb4: MSTORE 00001bb5: PUSH1 0x20 00001bb7: PUSH1 0x04 00001bb9: DUP3 00001bba: ADD 00001bbb: MSTORE 00001bbc: PUSH1 0x19 00001bbe: PUSH1 0x24 00001bc0: DUP3 00001bc1: ADD 00001bc2: MSTORE 00001bc3: PUSH32 0x43726f776473616c653a20776569416d6f756e74206973203000000000000000 00001be4: PUSH1 0x44 00001be6: DUP3 00001be7: ADD 00001be8: MSTORE 00001be9: SWAP1 00001bea: MLOAD 00001beb: SWAP1 00001bec: DUP2 00001bed: SWAP1 00001bee: SUB 00001bef: PUSH1 0x64 00001bf1: ADD 00001bf2: SWAP1 00001bf3: REVERT 00001bf4: JUMPDEST 00001bf5: PUSH1 0x00 00001bf7: DUP3 00001bf8: PUSH2 0x1c03 00001bfb: JUMPI 00001bfc: POP 00001bfd: PUSH1 0x00 00001bff: PUSH2 0x083e 00001c02: JUMP 00001c03: JUMPDEST 00001c04: DUP3 00001c05: DUP3 00001c06: MUL 00001c07: DUP3 00001c08: DUP5 00001c09: DUP3 00001c0a: DUP2 00001c0b: PUSH2 0x1c10 00001c0e: JUMPI 00001c0f: INVALID 00001c10: JUMPDEST 00001c11: DIV 00001c12: EQ 00001c13: PUSH2 0x1789 00001c16: JUMPI 00001c17: PUSH1 0x40 00001c19: MLOAD 00001c1a: PUSH1 0x01 00001c1c: PUSH1 0xe5 00001c1e: SHL 00001c1f: PUSH3 0x461bcd 00001c23: MUL 00001c24: DUP2 00001c25: MSTORE 00001c26: PUSH1 0x04 00001c28: ADD 00001c29: DUP1 00001c2a: DUP1 00001c2b: PUSH1 0x20 00001c2d: ADD 00001c2e: DUP3 00001c2f: DUP2 00001c30: SUB 00001c31: DUP3 00001c32: MSTORE 00001c33: PUSH1 0x21 00001c35: DUP2 00001c36: MSTORE 00001c37: PUSH1 0x20 00001c39: ADD 00001c3a: DUP1 00001c3b: PUSH2 0x226d 00001c3e: PUSH1 0x21 00001c40: SWAP2 00001c41: CODECOPY 00001c42: PUSH1 0x40 00001c44: ADD 00001c45: SWAP2 00001c46: POP 00001c47: POP 00001c48: PUSH1 0x40 00001c4a: MLOAD 00001c4b: DUP1 00001c4c: SWAP2 00001c4d: SUB 00001c4e: SWAP1 00001c4f: REVERT 00001c50: JUMPDEST 00001c51: PUSH1 0x05 00001c53: SLOAD 00001c54: PUSH2 0x1698 00001c57: SWAP1 00001c58: PUSH1 0x01 00001c5a: PUSH1 0x01 00001c5c: PUSH1 0xa0 00001c5e: SHL 00001c5f: SUB 00001c60: AND 00001c61: DUP4 00001c62: DUP4 00001c63: PUSH4 0xffffffff 00001c68: PUSH2 0x1ddf 00001c6b: AND 00001c6c: JUMP 00001c6d: JUMPDEST 00001c6e: PUSH1 0x00 00001c70: PUSH2 0x1789 00001c73: DUP4 00001c74: DUP4 00001c75: PUSH1 0x40 00001c77: MLOAD 00001c78: DUP1 00001c79: PUSH1 0x40 00001c7b: ADD 00001c7c: PUSH1 0x40 00001c7e: MSTORE 00001c7f: DUP1 00001c80: PUSH1 0x1e 00001c82: DUP2 00001c83: MSTORE 00001c84: PUSH1 0x20 00001c86: ADD 00001c87: PUSH32 0x536166654d6174683a207375627472616374696f6e206f766572666c6f770000 00001ca8: DUP2 00001ca9: MSTORE 00001caa: POP 00001cab: PUSH2 0x1e34 00001cae: JUMP 00001caf: JUMPDEST 00001cb0: PUSH1 0x00 00001cb2: PUSH2 0x1789 00001cb5: DUP4 00001cb6: DUP4 00001cb7: PUSH1 0x40 00001cb9: MLOAD 00001cba: DUP1 00001cbb: PUSH1 0x40 00001cbd: ADD 00001cbe: PUSH1 0x40 00001cc0: MSTORE 00001cc1: DUP1 00001cc2: PUSH1 0x1a 00001cc4: DUP2 00001cc5: MSTORE 00001cc6: PUSH1 0x20 00001cc8: ADD 00001cc9: PUSH32 0x536166654d6174683a206469766973696f6e206279207a65726f000000000000 00001cea: DUP2 00001ceb: MSTORE 00001cec: POP 00001ced: PUSH2 0x1ece 00001cf0: JUMP 00001cf1: JUMPDEST 00001cf2: PUSH2 0x1cfb 00001cf5: DUP3 00001cf6: DUP3 00001cf7: PUSH2 0x19af 00001cfa: JUMP 00001cfb: JUMPDEST 00001cfc: PUSH2 0x1d39 00001cff: JUMPI 00001d00: PUSH1 0x40 00001d02: MLOAD 00001d03: PUSH1 0x01 00001d05: PUSH1 0xe5 00001d07: SHL 00001d08: PUSH3 0x461bcd 00001d0c: MUL 00001d0d: DUP2 00001d0e: MSTORE 00001d0f: PUSH1 0x04 00001d11: ADD 00001d12: DUP1 00001d13: DUP1 00001d14: PUSH1 0x20 00001d16: ADD 00001d17: DUP3 00001d18: DUP2 00001d19: SUB 00001d1a: DUP3 00001d1b: MSTORE 00001d1c: PUSH1 0x21 00001d1e: DUP2 00001d1f: MSTORE 00001d20: PUSH1 0x20 00001d22: ADD 00001d23: DUP1 00001d24: PUSH2 0x2223 00001d27: PUSH1 0x21 00001d29: SWAP2 00001d2a: CODECOPY 00001d2b: PUSH1 0x40 00001d2d: ADD 00001d2e: SWAP2 00001d2f: POP 00001d30: POP 00001d31: PUSH1 0x40 00001d33: MLOAD 00001d34: DUP1 00001d35: SWAP2 00001d36: SUB 00001d37: SWAP1 00001d38: REVERT 00001d39: JUMPDEST 00001d3a: PUSH1 0x01 00001d3c: PUSH1 0x01 00001d3e: PUSH1 0xa0 00001d40: SHL 00001d41: SUB 00001d42: AND 00001d43: PUSH1 0x00 00001d45: SWAP1 00001d46: DUP2 00001d47: MSTORE 00001d48: PUSH1 0x20 00001d4a: SWAP2 00001d4b: SWAP1 00001d4c: SWAP2 00001d4d: MSTORE 00001d4e: PUSH1 0x40 00001d50: SWAP1 00001d51: KECCAK256 00001d52: DUP1 00001d53: SLOAD 00001d54: PUSH1 0xff 00001d56: NOT 00001d57: AND 00001d58: SWAP1 00001d59: SSTORE 00001d5a: JUMP 00001d5b: JUMPDEST 00001d5c: PUSH2 0x1d65 00001d5f: DUP3 00001d60: DUP3 00001d61: PUSH2 0x19af 00001d64: JUMP 00001d65: JUMPDEST 00001d66: ISZERO 00001d67: PUSH2 0x1dba 00001d6a: JUMPI 00001d6b: PUSH1 0x40 00001d6d: DUP1 00001d6e: MLOAD 00001d6f: PUSH1 0x01 00001d71: PUSH1 0xe5 00001d73: SHL 00001d74: PUSH3 0x461bcd 00001d78: MUL 00001d79: DUP2 00001d7a: MSTORE 00001d7b: PUSH1 0x20 00001d7d: PUSH1 0x04 00001d7f: DUP3 00001d80: ADD 00001d81: MSTORE 00001d82: PUSH1 0x1f 00001d84: PUSH1 0x24 00001d86: DUP3 00001d87: ADD 00001d88: MSTORE 00001d89: PUSH32 0x526f6c65733a206163636f756e7420616c72656164792068617320726f6c6500 00001daa: PUSH1 0x44 00001dac: DUP3 00001dad: ADD 00001dae: MSTORE 00001daf: SWAP1 00001db0: MLOAD 00001db1: SWAP1 00001db2: DUP2 00001db3: SWAP1 00001db4: SUB 00001db5: PUSH1 0x64 00001db7: ADD 00001db8: SWAP1 00001db9: REVERT 00001dba: JUMPDEST 00001dbb: PUSH1 0x01 00001dbd: PUSH1 0x01 00001dbf: PUSH1 0xa0 00001dc1: SHL 00001dc2: SUB 00001dc3: AND 00001dc4: PUSH1 0x00 00001dc6: SWAP1 00001dc7: DUP2 00001dc8: MSTORE 00001dc9: PUSH1 0x20 00001dcb: SWAP2 00001dcc: SWAP1 00001dcd: SWAP2 00001dce: MSTORE 00001dcf: PUSH1 0x40 00001dd1: SWAP1 00001dd2: KECCAK256 00001dd3: DUP1 00001dd4: SLOAD 00001dd5: PUSH1 0xff 00001dd7: NOT 00001dd8: AND 00001dd9: PUSH1 0x01 00001ddb: OR 00001ddc: SWAP1 00001ddd: SSTORE 00001dde: JUMP 00001ddf: JUMPDEST 00001de0: PUSH1 0x40 00001de2: DUP1 00001de3: MLOAD 00001de4: PUSH1 0x01 00001de6: PUSH1 0x01 00001de8: PUSH1 0xa0 00001dea: SHL 00001deb: SUB 00001dec: DUP5 00001ded: AND 00001dee: PUSH1 0x24 00001df0: DUP3 00001df1: ADD 00001df2: MSTORE 00001df3: PUSH1 0x44 00001df5: DUP1 00001df6: DUP3 00001df7: ADD 00001df8: DUP5 00001df9: SWAP1 00001dfa: MSTORE 00001dfb: DUP3 00001dfc: MLOAD 00001dfd: DUP1 00001dfe: DUP4 00001dff: SUB 00001e00: SWAP1 00001e01: SWAP2 00001e02: ADD 00001e03: DUP2 00001e04: MSTORE 00001e05: PUSH1 0x64 00001e07: SWAP1 00001e08: SWAP2 00001e09: ADD 00001e0a: SWAP1 00001e0b: SWAP2 00001e0c: MSTORE 00001e0d: PUSH1 0x20 00001e0f: DUP2 00001e10: ADD 00001e11: DUP1 00001e12: MLOAD 00001e13: PUSH1 0x01 00001e15: PUSH1 0x01 00001e17: PUSH1 0xe0 00001e19: SHL 00001e1a: SUB 00001e1b: AND 00001e1c: PUSH1 0x01 00001e1e: PUSH1 0xe0 00001e20: SHL 00001e21: PUSH4 0xa9059cbb 00001e26: MUL 00001e27: OR 00001e28: SWAP1 00001e29: MSTORE 00001e2a: PUSH2 0x097a 00001e2d: SWAP1 00001e2e: DUP5 00001e2f: SWAP1 00001e30: PUSH2 0x1f36 00001e33: JUMP 00001e34: JUMPDEST 00001e35: PUSH1 0x00 00001e37: DUP2 00001e38: DUP5 00001e39: DUP5 00001e3a: GT 00001e3b: ISZERO 00001e3c: PUSH2 0x1ec6 00001e3f: JUMPI 00001e40: PUSH1 0x40 00001e42: MLOAD 00001e43: PUSH1 0x01 00001e45: PUSH1 0xe5 00001e47: SHL 00001e48: PUSH3 0x461bcd 00001e4c: MUL 00001e4d: DUP2 00001e4e: MSTORE 00001e4f: PUSH1 0x04 00001e51: ADD 00001e52: DUP1 00001e53: DUP1 00001e54: PUSH1 0x20 00001e56: ADD 00001e57: DUP3 00001e58: DUP2 00001e59: SUB 00001e5a: DUP3 00001e5b: MSTORE 00001e5c: DUP4 00001e5d: DUP2 00001e5e: DUP2 00001e5f: MLOAD 00001e60: DUP2 00001e61: MSTORE 00001e62: PUSH1 0x20 00001e64: ADD 00001e65: SWAP2 00001e66: POP 00001e67: DUP1 00001e68: MLOAD 00001e69: SWAP1 00001e6a: PUSH1 0x20 00001e6c: ADD 00001e6d: SWAP1 00001e6e: DUP1 00001e6f: DUP4 00001e70: DUP4 00001e71: PUSH1 0x00 00001e73: JUMPDEST 00001e74: DUP4 00001e75: DUP2 00001e76: LT 00001e77: ISZERO 00001e78: PUSH2 0x1e8b 00001e7b: JUMPI 00001e7c: DUP2 00001e7d: DUP2 00001e7e: ADD 00001e7f: MLOAD 00001e80: DUP4 00001e81: DUP3 00001e82: ADD 00001e83: MSTORE 00001e84: PUSH1 0x20 00001e86: ADD 00001e87: PUSH2 0x1e73 00001e8a: JUMP 00001e8b: JUMPDEST 00001e8c: POP 00001e8d: POP 00001e8e: POP 00001e8f: POP 00001e90: SWAP1 00001e91: POP 00001e92: SWAP1 00001e93: DUP2 00001e94: ADD 00001e95: SWAP1 00001e96: PUSH1 0x1f 00001e98: AND 00001e99: DUP1 00001e9a: ISZERO 00001e9b: PUSH2 0x1eb8 00001e9e: JUMPI 00001e9f: DUP1 00001ea0: DUP3 00001ea1: SUB 00001ea2: DUP1 00001ea3: MLOAD 00001ea4: PUSH1 0x01 00001ea6: DUP4 00001ea7: PUSH1 0x20 00001ea9: SUB 00001eaa: PUSH2 0x0100 00001ead: EXP 00001eae: SUB 00001eaf: NOT 00001eb0: AND 00001eb1: DUP2 00001eb2: MSTORE 00001eb3: PUSH1 0x20 00001eb5: ADD 00001eb6: SWAP2 00001eb7: POP 00001eb8: JUMPDEST 00001eb9: POP 00001eba: SWAP3 00001ebb: POP 00001ebc: POP 00001ebd: POP 00001ebe: PUSH1 0x40 00001ec0: MLOAD 00001ec1: DUP1 00001ec2: SWAP2 00001ec3: SUB 00001ec4: SWAP1 00001ec5: REVERT 00001ec6: JUMPDEST 00001ec7: POP 00001ec8: POP 00001ec9: POP 00001eca: SWAP1 00001ecb: SUB 00001ecc: SWAP1 00001ecd: JUMP 00001ece: JUMPDEST 00001ecf: PUSH1 0x00 00001ed1: DUP2 00001ed2: DUP4 00001ed3: PUSH2 0x1f20 00001ed6: JUMPI 00001ed7: PUSH1 0x40 00001ed9: MLOAD 00001eda: PUSH1 0x01 00001edc: PUSH1 0xe5 00001ede: SHL 00001edf: PUSH3 0x461bcd 00001ee3: MUL 00001ee4: DUP2 00001ee5: MSTORE 00001ee6: PUSH1 0x20 00001ee8: PUSH1 0x04 00001eea: DUP3 00001eeb: ADD 00001eec: DUP2 00001eed: DUP2 00001eee: MSTORE 00001eef: DUP4 00001ef0: MLOAD 00001ef1: PUSH1 0x24 00001ef3: DUP5 00001ef4: ADD 00001ef5: MSTORE 00001ef6: DUP4 00001ef7: MLOAD 00001ef8: SWAP1 00001ef9: SWAP3 00001efa: DUP4 00001efb: SWAP3 00001efc: PUSH1 0x44 00001efe: SWAP1 00001eff: SWAP2 00001f00: ADD 00001f01: SWAP2 00001f02: SWAP1 00001f03: DUP6 00001f04: ADD 00001f05: SWAP1 00001f06: DUP1 00001f07: DUP4 00001f08: DUP4 00001f09: PUSH1 0x00 00001f0b: DUP4 00001f0c: ISZERO 00001f0d: PUSH2 0x1e8b 00001f10: JUMPI 00001f11: DUP2 00001f12: DUP2 00001f13: ADD 00001f14: MLOAD 00001f15: DUP4 00001f16: DUP3 00001f17: ADD 00001f18: MSTORE 00001f19: PUSH1 0x20 00001f1b: ADD 00001f1c: PUSH2 0x1e73 00001f1f: JUMP 00001f20: JUMPDEST 00001f21: POP 00001f22: PUSH1 0x00 00001f24: DUP4 00001f25: DUP6 00001f26: DUP2 00001f27: PUSH2 0x1f2c 00001f2a: JUMPI 00001f2b: INVALID 00001f2c: JUMPDEST 00001f2d: DIV 00001f2e: SWAP6 00001f2f: SWAP5 00001f30: POP 00001f31: POP 00001f32: POP 00001f33: POP 00001f34: POP 00001f35: JUMP 00001f36: JUMPDEST 00001f37: PUSH2 0x1f48 00001f3a: DUP3 00001f3b: PUSH1 0x01 00001f3d: PUSH1 0x01 00001f3f: PUSH1 0xa0 00001f41: SHL 00001f42: SUB 00001f43: AND 00001f44: PUSH2 0x20fd 00001f47: JUMP 00001f48: JUMPDEST 00001f49: PUSH2 0x1f9c 00001f4c: JUMPI 00001f4d: PUSH1 0x40 00001f4f: DUP1 00001f50: MLOAD 00001f51: PUSH1 0x01 00001f53: PUSH1 0xe5 00001f55: SHL 00001f56: PUSH3 0x461bcd 00001f5a: MUL 00001f5b: DUP2 00001f5c: MSTORE 00001f5d: PUSH1 0x20 00001f5f: PUSH1 0x04 00001f61: DUP3 00001f62: ADD 00001f63: MSTORE 00001f64: PUSH1 0x1f 00001f66: PUSH1 0x24 00001f68: DUP3 00001f69: ADD 00001f6a: MSTORE 00001f6b: PUSH32 0x5361666545524332303a2063616c6c20746f206e6f6e2d636f6e747261637400 00001f8c: PUSH1 0x44 00001f8e: DUP3 00001f8f: ADD 00001f90: MSTORE 00001f91: SWAP1 00001f92: MLOAD 00001f93: SWAP1 00001f94: DUP2 00001f95: SWAP1 00001f96: SUB 00001f97: PUSH1 0x64 00001f99: ADD 00001f9a: SWAP1 00001f9b: REVERT 00001f9c: JUMPDEST 00001f9d: PUSH1 0x00 00001f9f: PUSH1 0x60 00001fa1: DUP4 00001fa2: PUSH1 0x01 00001fa4: PUSH1 0x01 00001fa6: PUSH1 0xa0 00001fa8: SHL 00001fa9: SUB 00001faa: AND 00001fab: DUP4 00001fac: PUSH1 0x40 00001fae: MLOAD 00001faf: DUP1 00001fb0: DUP3 00001fb1: DUP1 00001fb2: MLOAD 00001fb3: SWAP1 00001fb4: PUSH1 0x20 00001fb6: ADD 00001fb7: SWAP1 00001fb8: DUP1 00001fb9: DUP4 00001fba: DUP4 00001fbb: JUMPDEST 00001fbc: PUSH1 0x20 00001fbe: DUP4 00001fbf: LT 00001fc0: PUSH2 0x1fda 00001fc3: JUMPI 00001fc4: DUP1 00001fc5: MLOAD 00001fc6: DUP3 00001fc7: MSTORE 00001fc8: PUSH1 0x1f 00001fca: NOT 00001fcb: SWAP1 00001fcc: SWAP3 00001fcd: ADD 00001fce: SWAP2 00001fcf: PUSH1 0x20 00001fd1: SWAP2 00001fd2: DUP3 00001fd3: ADD 00001fd4: SWAP2 00001fd5: ADD 00001fd6: PUSH2 0x1fbb 00001fd9: JUMP 00001fda: JUMPDEST 00001fdb: PUSH1 0x01 00001fdd: DUP4 00001fde: PUSH1 0x20 00001fe0: SUB 00001fe1: PUSH2 0x0100 00001fe4: EXP 00001fe5: SUB 00001fe6: DUP1 00001fe7: NOT 00001fe8: DUP3 00001fe9: MLOAD 00001fea: AND 00001feb: DUP2 00001fec: DUP5 00001fed: MLOAD 00001fee: AND 00001fef: DUP1 00001ff0: DUP3 00001ff1: OR 00001ff2: DUP6 00001ff3: MSTORE 00001ff4: POP 00001ff5: POP 00001ff6: POP 00001ff7: POP 00001ff8: POP 00001ff9: POP 00001ffa: SWAP1 00001ffb: POP 00001ffc: ADD 00001ffd: SWAP2 00001ffe: POP 00001fff: POP 00002000: PUSH1 0x00 00002002: PUSH1 0x40 00002004: MLOAD 00002005: DUP1 00002006: DUP4 00002007: SUB 00002008: DUP2 00002009: PUSH1 0x00 0000200b: DUP7 0000200c: GAS 0000200d: CALL 0000200e: SWAP2 0000200f: POP 00002010: POP 00002011: RETURNDATASIZE 00002012: DUP1 00002013: PUSH1 0x00 00002015: DUP2 00002016: EQ 00002017: PUSH2 0x203c 0000201a: JUMPI 0000201b: PUSH1 0x40 0000201d: MLOAD 0000201e: SWAP2 0000201f: POP 00002020: PUSH1 0x1f 00002022: NOT 00002023: PUSH1 0x3f 00002025: RETURNDATASIZE 00002026: ADD 00002027: AND 00002028: DUP3 00002029: ADD 0000202a: PUSH1 0x40 0000202c: MSTORE 0000202d: RETURNDATASIZE 0000202e: DUP3 0000202f: MSTORE 00002030: RETURNDATASIZE 00002031: PUSH1 0x00 00002033: PUSH1 0x20 00002035: DUP5 00002036: ADD 00002037: RETURNDATACOPY 00002038: PUSH2 0x2041 0000203b: JUMP 0000203c: JUMPDEST 0000203d: PUSH1 0x60 0000203f: SWAP2 00002040: POP 00002041: JUMPDEST 00002042: POP 00002043: SWAP2 00002044: POP 00002045: SWAP2 00002046: POP 00002047: DUP2 00002048: PUSH2 0x209b 0000204b: JUMPI 0000204c: PUSH1 0x40 0000204e: DUP1 0000204f: MLOAD 00002050: PUSH1 0x01 00002052: PUSH1 0xe5 00002054: SHL 00002055: PUSH3 0x461bcd 00002059: MUL 0000205a: DUP2 0000205b: MSTORE 0000205c: PUSH1 0x20 0000205e: PUSH1 0x04 00002060: DUP3 00002061: ADD 00002062: DUP2 00002063: SWAP1 00002064: MSTORE 00002065: PUSH1 0x24 00002067: DUP3 00002068: ADD 00002069: MSTORE 0000206a: PUSH32 0x5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564 0000208b: PUSH1 0x44 0000208d: DUP3 0000208e: ADD 0000208f: MSTORE 00002090: SWAP1 00002091: MLOAD 00002092: SWAP1 00002093: DUP2 00002094: SWAP1 00002095: SUB 00002096: PUSH1 0x64 00002098: ADD 00002099: SWAP1 0000209a: REVERT 0000209b: JUMPDEST 0000209c: DUP1 0000209d: MLOAD 0000209e: ISZERO 0000209f: PUSH2 0x20f7 000020a2: JUMPI 000020a3: DUP1 000020a4: DUP1 000020a5: PUSH1 0x20 000020a7: ADD 000020a8: SWAP1 000020a9: MLOAD 000020aa: PUSH1 0x20 000020ac: DUP2 000020ad: LT 000020ae: ISZERO 000020af: PUSH2 0x20b7 000020b2: JUMPI 000020b3: PUSH1 0x00 000020b5: DUP1 000020b6: REVERT 000020b7: JUMPDEST 000020b8: POP 000020b9: MLOAD 000020ba: PUSH2 0x20f7 000020bd: JUMPI 000020be: PUSH1 0x40 000020c0: MLOAD 000020c1: PUSH1 0x01 000020c3: PUSH1 0xe5 000020c5: SHL 000020c6: PUSH3 0x461bcd 000020ca: MUL 000020cb: DUP2 000020cc: MSTORE 000020cd: PUSH1 0x04 000020cf: ADD 000020d0: DUP1 000020d1: DUP1 000020d2: PUSH1 0x20 000020d4: ADD 000020d5: DUP3 000020d6: DUP2 000020d7: SUB 000020d8: DUP3 000020d9: MSTORE 000020da: PUSH1 0x2a 000020dc: DUP2 000020dd: MSTORE 000020de: PUSH1 0x20 000020e0: ADD 000020e1: DUP1 000020e2: PUSH2 0x22fa 000020e5: PUSH1 0x2a 000020e7: SWAP2 000020e8: CODECOPY 000020e9: PUSH1 0x40 000020eb: ADD 000020ec: SWAP2 000020ed: POP 000020ee: POP 000020ef: PUSH1 0x40 000020f1: MLOAD 000020f2: DUP1 000020f3: SWAP2 000020f4: SUB 000020f5: SWAP1 000020f6: REVERT 000020f7: JUMPDEST 000020f8: POP 000020f9: POP 000020fa: POP 000020fb: POP 000020fc: JUMP 000020fd: JUMPDEST 000020fe: PUSH1 0x00 00002100: DUP2 00002101: EXTCODEHASH 00002102: PUSH32 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 00002123: DUP2 00002124: DUP2 00002125: EQ 00002126: DUP1 00002127: ISZERO 00002128: SWAP1 00002129: PUSH2 0x2131 0000212c: JUMPI 0000212d: POP 0000212e: DUP2 0000212f: ISZERO 00002130: ISZERO 00002131: JUMPDEST 00002132: SWAP5 00002133: SWAP4 00002134: POP 00002135: POP 00002136: POP 00002137: POP 00002138: JUMP 00002139: JUMPDEST 0000213a: PUSH1 0x40 0000213c: MLOAD 0000213d: DUP1 0000213e: PUSH1 0xe0 00002140: ADD 00002141: PUSH1 0x40 00002143: MSTORE 00002144: DUP1 00002145: PUSH1 0x00 00002147: DUP2 00002148: MSTORE 00002149: PUSH1 0x20 0000214b: ADD 0000214c: PUSH1 0x00 0000214e: DUP2 0000214f: MSTORE 00002150: PUSH1 0x20 00002152: ADD 00002153: PUSH1 0x00 00002155: DUP2 00002156: MSTORE 00002157: PUSH1 0x20 00002159: ADD 0000215a: PUSH1 0x00 0000215c: DUP2 0000215d: MSTORE 0000215e: PUSH1 0x20 00002160: ADD 00002161: PUSH1 0x00 00002163: DUP2 00002164: MSTORE 00002165: PUSH1 0x20 00002167: ADD 00002168: PUSH1 0x00 0000216a: DUP2 0000216b: MSTORE 0000216c: PUSH1 0x20 0000216e: ADD 0000216f: PUSH1 0x00 00002171: DUP2 00002172: MSTORE 00002173: POP 00002174: SWAP1 00002175: JUMP 00002176: JUMPDEST 00002177: PUSH1 0x40 00002179: MLOAD 0000217a: DUP1 0000217b: PUSH1 0x20 0000217d: ADD 0000217e: PUSH1 0x40 00002180: MSTORE 00002181: DUP1 00002182: PUSH1 0x00 00002184: DUP2 00002185: MSTORE 00002186: POP 00002187: SWAP1 00002188: JUMP 00002189: INVALID 0000218a: POP 0000218b: PUSH2 0x7573 0000218e: PUSH6 0x72526f6c653a 00002195: KECCAK256 00002196: PUSH4 0x616c6c65 0000219b: PUSH19 0x20646f6573206e6f7420686176652074686520 000021af: POP 000021b0: PUSH2 0x7573 000021b3: PUSH6 0x7220726f6c65 000021ba: UNKNOWN(0x4F) 000021bb: PUSH24 0x6e61626c653a206e6577206f776e65722069732074686520 000021d4: PUSH27 0x65726f206164647265737347484343726f7764616c653a2063726f 000021f0: PUSH24 0x6473616c65206e6f74207374617274656447484343726f77 00002209: PUSH5 0x616c653a20 0000220f: PUSH19 0x6f756e6420616d6f756e74206f7665666c6f77 00002223: MSTORE 00002224: PUSH16 0x6c65733a206163636f756e7420646f65 00002235: PUSH20 0x206e6f74206861766520726f6c6547484343726f 0000224a: PUSH24 0x64616c653a206d617820616d6f756e742072656163686564 00002263: KECCAK256 00002264: PUSH7 0x6f7220726f756e 0000226c: PUSH5 0x536166654d 00002272: PUSH2 0x7468 00002275: GASPRICE 00002276: KECCAK256 00002277: PUSH14 0x756c7469706c69636174696f6e20 00002286: PUSH16 0x766572666c6f774f776e61626c653a20 00002297: PUSH4 0x616c6c65 0000229c: PUSH19 0x206973206e6f7420746865206f776e6572526f 000022b0: PUSH13 0x65733a206163636f756e742069 000022be: PUSH20 0x20746865207a65726f206164647265737343726f 000022d3: PUSH24 0x6473616c653a2062656e6566696369617279206973207468 000022ec: PUSH6 0x207a65726f20 000022f3: PUSH2 0x6464 000022f6: PUSH19 0x6573735361666545524332303a204552433230 0000230a: KECCAK256 0000230b: PUSH16 0x7065726174696f6e20646964206e6f74 0000231c: KECCAK256 0000231d: PUSH20 0x756363656564a165627a7a723058203468515453 00002332: RETURN 00002333: MSTORE 00002334: UNKNOWN(0xEC) 00002335: PUSH16 0x7b855ee391f6d2617608325baa72f7e2 00002346: DUP6 00002347: UNKNOWN(0x21) 00002348: SIGNEXTEND 00002349: UNKNOWN(0xD8) 0000234a: UNKNOWN(0xD1) 0000234b: JUMPI 0000234c: UNKNOWN(0xB5) 0000234d: STOP 0000234e: UNKNOWN(0x29)
| Severity | Category | Tool | Title | Confidence | Validated | Confirmed | Details |
|---|---|---|---|---|---|---|---|
| high | other | detector | Untrusted CALL target/value reachable | 60 | no | no |
viewtrace_id: 0x3949ed643df09b79a805eb1cd2cf0d8cc0aacdbc8d59c1119708f832ebabcb70
call_targets:
0xda9f13722fef7a6357944622f583285da14c90a5
target_varies:
no
classification:
constant_target
validation_json{
"sink": "CALL",
"errors": 0,
"status": "sink_reached",
"attempts": 1,
"trace_id": "0x3949ed643df09b79a805eb1cd2cf0d8cc0aacdbc8d59c1119708f832ebabcb70",
"confirmed": false,
"trace_mode": "callTracer",
"call_targets": [
"0xda9f13722fef7a6357944622f583285da14c90a5"
],
"matched_probe": null,
"target_varies": false,
"classification": "constant_target"
}
witness_json{
"notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
"constraints": [],
"entrypoints": [
{
"calldata": "0xeadf6258",
"selector": "0xeadf6258",
"calldata_variants": [
"0xeadf6258",
"0xeadf62580000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xec8ac4d8",
"selector": "0xec8ac4d8",
"calldata_variants": [
"0xec8ac4d8",
"0xec8ac4d80000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xf2fde38b",
"selector": "0xf2fde38b",
"calldata_variants": [
"0xf2fde38b",
"0xf2fde38b0000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xfc0c546a",
"selector": "0xfc0c546a",
"calldata_variants": [
"0xfc0c546a",
"0xfc0c546a0000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xabcb4223",
"selector": "0xabcb4223",
"calldata_variants": [
"0xabcb4223",
"0xabcb42230000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xba166a39",
"selector": "0xba166a39",
"calldata_variants": [
"0xba166a39",
"0xba166a390000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xc4af19ce",
"selector": "0xc4af19ce",
"calldata_variants": [
"0xc4af19ce",
"0xc4af19ce0000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xe4b65f5b",
"selector": "0xe4b65f5b",
"calldata_variants": [
"0xe4b65f5b",
"0xe4b65f5b0000000000000000000000000000000000000000000000000000000000000000"
]
}
]
}
evidence_json{
"examples": [
{
"pc": 2404,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "computed",
"target_expression_category": "computed"
},
{
"pc": 4106,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "computed",
"target_expression_category": "computed"
},
{
"pc": 6184,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "computed",
"target_expression_category": "computed"
}
],
"call_count": 6,
"guards_detected": [],
"untrusted_call_count": 6
}
|
| high | other | detector | ETH value transfer possible | 55 | no | no |
viewtrace_id: 0x3949ed643df09b79a805eb1cd2cf0d8cc0aacdbc8d59c1119708f832ebabcb70
call_targets:
0xda9f13722fef7a6357944622f583285da14c90a5
target_varies:
no
classification:
constant_target
validation_json{
"sink": "CALL",
"errors": 0,
"status": "sink_reached",
"attempts": 1,
"trace_id": "0x3949ed643df09b79a805eb1cd2cf0d8cc0aacdbc8d59c1119708f832ebabcb70",
"confirmed": false,
"trace_mode": "callTracer",
"call_targets": [
"0xda9f13722fef7a6357944622f583285da14c90a5"
],
"matched_probe": null,
"target_varies": false,
"classification": "constant_target"
}
witness_json{
"notes": "heuristic witness; entrypoints are best-effort selectors with zeroed calldata",
"constraints": [],
"entrypoints": [
{
"calldata": "0xeadf6258",
"selector": "0xeadf6258",
"calldata_variants": [
"0xeadf6258",
"0xeadf62580000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xec8ac4d8",
"selector": "0xec8ac4d8",
"calldata_variants": [
"0xec8ac4d8",
"0xec8ac4d80000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xf2fde38b",
"selector": "0xf2fde38b",
"calldata_variants": [
"0xf2fde38b",
"0xf2fde38b0000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xfc0c546a",
"selector": "0xfc0c546a",
"calldata_variants": [
"0xfc0c546a",
"0xfc0c546a0000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xabcb4223",
"selector": "0xabcb4223",
"calldata_variants": [
"0xabcb4223",
"0xabcb42230000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xba166a39",
"selector": "0xba166a39",
"calldata_variants": [
"0xba166a39",
"0xba166a390000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xc4af19ce",
"selector": "0xc4af19ce",
"calldata_variants": [
"0xc4af19ce",
"0xc4af19ce0000000000000000000000000000000000000000000000000000000000000000"
]
},
{
"calldata": "0xe4b65f5b",
"selector": "0xe4b65f5b",
"calldata_variants": [
"0xe4b65f5b",
"0xe4b65f5b0000000000000000000000000000000000000000000000000000000000000000"
]
}
]
}
evidence_json{
"examples": [
{
"pc": 2404,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "computed",
"target_expression_category": "computed"
},
{
"pc": 4106,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "computed",
"target_expression_category": "computed"
},
{
"pc": 6184,
"opcode": "CALL",
"returndata_checked": null,
"value_expression_category": "computed",
"target_expression_category": "computed"
}
],
"eth_value_calls": 6,
"guards_detected": []
}
|
| high | other | codex | ETH distribution accounting is never persisted, so crossing the payout threshold can brick subsequent purchases | 85 | no | — |
viewevidence_json{
"evidence": "`currentFunds` is derived from `_weiRaised.sub(_weiDistributed)`, but line 827 calls `_weiDistributed.add(currentFunds);` without storing the result. The contract therefore forgets every prior distribution.",
"locations": [
"contracts/Contract.sol:818",
"contracts/Contract.sol:821",
"contracts/Contract.sol:823",
"contracts/Contract.sol:825",
"contracts/Contract.sol:827"
],
"recommendation": "Persist the distribution state with `_weiDistributed = _weiDistributed.add(currentFunds);` before returning, and add tests that cover multiple payout cycles after several purchases.",
"exploit_scenario": "Once total raised ETH reaches `_triggerAmount`, `_forwardFunds()` distributes the full `currentFunds` balance to the three wallets. Because `_weiDistributed` is not assigned back, it stays `0`. On the next purchase, `currentFunds` is recalculated as the cumulative `_weiRaised`, not the undistributed amount, so the function attempts to pay out more ETH than the contract actually holds and the purchase reverts. Any buyer can be the one who pushes the sale over the threshold and trigger this broken state."
}
|
| high | reentrancy | slither | Reentrancy in Crowdsale.buyTokens(address) (contracts/Contract.sol#698-728): | 85 | no | — |
viewevidence_json{
"impact": "High",
"detector": "reentrancy-eth",
"elements": [
{
"name": "buyTokens",
"type": "function",
"source_mapping": {
"lines": [
698,
699,
700,
701,
702,
703,
704,
705,
706,
707,
708,
709,
710,
711,
712,
713,
714,
715,
716,
717,
718,
719,
720,
721,
722,
723,
724,
725,
726,
727,
728
],
"start": 27288,
"length": 884,
"ending_column": 22,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 63,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"type_specific_fields": {
"parent": {
"name": "Crowdsale",
"type": "contract",
"source_mapping": {
"lines": [
570,
571,
572,
573,
574,
575,
576,
577,
578,
579,
580,
581,
582,
583,
584,
585,
586,
587,
588,
589,
590,
591,
592,
593,
594,
595,
596,
597,
598,
599,
600,
601,
602,
603,
604,
605,
606,
607,
608,
609,
610,
611,
612,
613,
614,
615,
616,
617,
618,
619,
620,
621,
622,
623,
624,
625,
626,
627,
628,
629,
630,
631,
632,
633,
634,
635,
636,
637,
638,
639,
640,
641,
642,
643,
644,
645,
646,
647,
648,
649,
650,
651,
652,
653,
654,
655,
656,
657,
658,
659,
660,
661,
662,
663,
664,
665,
666,
667,
668,
669,
670,
671,
672,
673,
674,
675,
676,
677,
678,
679,
680,
681,
682,
683,
684,
685,
686,
687,
688,
689,
690,
691,
692,
693,
694,
695,
696,
697,
698,
699,
700,
701,
702,
703,
704,
705,
706,
707,
708,
709,
710,
711,
712,
713,
714,
715,
716,
717,
718,
719,
720,
721,
722,
723,
724,
725,
726,
727,
728,
729,
730,
731,
732,
733,
734,
735,
736,
737,
738,
739,
740,
741,
742,
743,
744,
745,
746,
747,
748,
749,
750,
751,
752,
753,
754,
755,
756,
757,
758,
759,
760,
761,
762,
763,
764,
765,
766,
767,
768,
769,
770,
771,
772,
773,
774,
775,
776,
777,
778,
779,
780,
781,
782,
783,
784,
785,
786,
787,
788,
789,
790,
791,
792,
793,
794,
795,
796,
797,
798,
799,
800,
801,
802,
803,
804,
805,
806,
807,
808,
809,
810,
811,
812,
813,
814,
815,
816,
817,
818,
819,
820,
821,
822,
823,
824,
825,
826,
827,
828,
829,
830,
831,
832,
833,
834,
835,
836,
837,
838,
839,
840,
841,
842,
843,
844,
845,
846,
847,
848,
849,
850,
851,
852,
853,
854,
855,
856,
857,
858,
859,
860,
861,
862,
863,
864,
865,
866,
867,
868,
869,
870
],
"start": 21490,
"length": 12690,
"ending_column": 35,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 35,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
}
},
"signature": "buyTokens(address)"
}
},
{
"name": "_processPurchase(beneficiary,tokens)",
"type": "node",
"source_mapping": {
"lines": [
718,
719,
720
],
"start": 27750,
"length": 37,
"ending_column": 28,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 2,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"additional_fields": {
"underlying_type": "external_calls"
},
"type_specific_fields": {
"parent": {
"name": "buyTokens",
"type": "function",
"source_mapping": {
"lines": [
698,
699,
700,
701,
702,
703,
704,
705,
706,
707,
708,
709,
710,
711,
712,
713,
714,
715,
716,
717,
718,
719,
720,
721,
722,
723,
724,
725,
726,
727,
728
],
"start": 27288,
"length": 884,
"ending_column": 22,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 63,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"type_specific_fields": {
"parent": {
"name": "Crowdsale",
"type": "contract",
"source_mapping": {
"lines": [
570,
571,
572,
573,
574,
575,
576,
577,
578,
579,
580,
581,
582,
583,
584,
585,
586,
587,
588,
589,
590,
591,
592,
593,
594,
595,
596,
597,
598,
599,
600,
601,
602,
603,
604,
605,
606,
607,
608,
609,
610,
611,
612,
613,
614,
615,
616,
617,
618,
619,
620,
621,
622,
623,
624,
625,
626,
627,
628,
629,
630,
631,
632,
633,
634,
635,
636,
637,
638,
639,
640,
641,
642,
643,
644,
645,
646,
647,
648,
649,
650,
651,
652,
653,
654,
655,
656,
657,
658,
659,
660,
661,
662,
663,
664,
665,
666,
667,
668,
669,
670,
671,
672,
673,
674,
675,
676,
677,
678,
679,
680,
681,
682,
683,
684,
685,
686,
687,
688,
689,
690,
691,
692,
693,
694,
695,
696,
697,
698,
699,
700,
701,
702,
703,
704,
705,
706,
707,
708,
709,
710,
711,
712,
713,
714,
715,
716,
717,
718,
719,
720,
721,
722,
723,
724,
725,
726,
727,
728,
729,
730,
731,
732,
733,
734,
735,
736,
737,
738,
739,
740,
741,
742,
743,
744,
745,
746,
747,
748,
749,
750,
751,
752,
753,
754,
755,
756,
757,
758,
759,
760,
761,
762,
763,
764,
765,
766,
767,
768,
769,
770,
771,
772,
773,
774,
775,
776,
777,
778,
779,
780,
781,
782,
783,
784,
785,
786,
787,
788,
789,
790,
791,
792,
793,
794,
795,
796,
797,
798,
799,
800,
801,
802,
803,
804,
805,
806,
807,
808,
809,
810,
811,
812,
813,
814,
815,
816,
817,
818,
819,
820,
821,
822,
823,
824,
825,
826,
827,
828,
829,
830,
831,
832,
833,
834,
835,
836,
837,
838,
839,
840,
841,
842,
843,
844,
845,
846,
847,
848,
849,
850,
851,
852,
853,
854,
855,
856,
857,
858,
859,
860,
861,
862,
863,
864,
865,
866,
867,
868,
869,
870
],
"start": 21490,
"length": 12690,
"ending_column": 35,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 35,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
}
},
"signature": "buyTokens(address)"
}
}
}
},
{
"name": "_token.safeTransfer(beneficiary,tokenAmount)",
"type": "node",
"source_mapping": {
"lines": [
766
],
"start": 29899,
"length": 45,
"ending_column": 80,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 35,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"additional_fields": {
"underlying_type": "external_calls_sending_eth"
},
"type_specific_fields": {
"parent": {
"name": "_deliverTokens",
"type": "function",
"source_mapping": {
"lines": [
762,
763,
764,
765,
766
],
"start": 29814,
"length": 137,
"ending_column": 87,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 102,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"type_specific_fields": {
"parent": {
"name": "Crowdsale",
"type": "contract",
"source_mapping": {
"lines": [
570,
571,
572,
573,
574,
575,
576,
577,
578,
579,
580,
581,
582,
583,
584,
585,
586,
587,
588,
589,
590,
591,
592,
593,
594,
595,
596,
597,
598,
599,
600,
601,
602,
603,
604,
605,
606,
607,
608,
609,
610,
611,
612,
613,
614,
615,
616,
617,
618,
619,
620,
621,
622,
623,
624,
625,
626,
627,
628,
629,
630,
631,
632,
633,
634,
635,
636,
637,
638,
639,
640,
641,
642,
643,
644,
645,
646,
647,
648,
649,
650,
651,
652,
653,
654,
655,
656,
657,
658,
659,
660,
661,
662,
663,
664,
665,
666,
667,
668,
669,
670,
671,
672,
673,
674,
675,
676,
677,
678,
679,
680,
681,
682,
683,
684,
685,
686,
687,
688,
689,
690,
691,
692,
693,
694,
695,
696,
697,
698,
699,
700,
701,
702,
703,
704,
705,
706,
707,
708,
709,
710,
711,
712,
713,
714,
715,
716,
717,
718,
719,
720,
721,
722,
723,
724,
725,
726,
727,
728,
729,
730,
731,
732,
733,
734,
735,
736,
737,
738,
739,
740,
741,
742,
743,
744,
745,
746,
747,
748,
749,
750,
751,
752,
753,
754,
755,
756,
757,
758,
759,
760,
761,
762,
763,
764,
765,
766,
767,
768,
769,
770,
771,
772,
773,
774,
775,
776,
777,
778,
779,
780,
781,
782,
783,
784,
785,
786,
787,
788,
789,
790,
791,
792,
793,
794,
795,
796,
797,
798,
799,
800,
801,
802,
803,
804,
805,
806,
807,
808,
809,
810,
811,
812,
813,
814,
815,
816,
817,
818,
819,
820,
821,
822,
823,
824,
825,
826,
827,
828,
829,
830,
831,
832,
833,
834,
835,
836,
837,
838,
839,
840,
841,
842,
843,
844,
845,
846,
847,
848,
849,
850,
851,
852,
853,
854,
855,
856,
857,
858,
859,
860,
861,
862,
863,
864,
865,
866,
867,
868,
869,
870
],
"start": 21490,
"length": 12690,
"ending_column": 35,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 35,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
}
},
"signature": "_deliverTokens(address,uint256)"
}
}
}
},
{
"name": "(success,returndata) = address(token).call(data)",
"type": "node",
"source_mapping": {
"lines": [
402,
403
],
"start": 15622,
"length": 67,
"ending_column": 25,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 40,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"additional_fields": {
"underlying_type": "external_calls_sending_eth"
},
"type_specific_fields": {
"parent": {
"name": "callOptionalReturn",
"type": "function",
"source_mapping": {
"lines": [
389,
390,
391,
392,
393,
394,
395,
396,
397,
398,
399,
400,
401,
402,
403,
404,
405,
406,
407,
408
],
"start": 14894,
"length": 1095,
"ending_column": 28,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 1,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"type_specific_fields": {
"parent": {
"name": "SafeERC20",
"type": "contract",
"source_mapping": {
"lines": [
352,
353,
354,
355,
356,
357,
358,
359,
360,
361,
362,
363,
364,
365,
366,
367,
368,
369,
370,
371,
372,
373,
374,
375,
376,
377,
378,
379,
380,
381,
382,
383,
384,
385,
386,
387,
388,
389,
390,
391,
392,
393,
394,
395,
396,
397,
398,
399,
400,
401,
402,
403,
404,
405,
406,
407,
408
],
"start": 12802,
"length": 3189,
"ending_column": 30,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 5,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
}
},
"signature": "callOptionalReturn(IERC20,bytes)"
}
}
}
},
{
"name": "_forwardFunds()",
"type": "node",
"source_mapping": {
"lines": [
722,
723
],
"start": 27931,
"length": 15,
"ending_column": 7,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 33,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"additional_fields": {
"underlying_type": "external_calls_sending_eth"
},
"type_specific_fields": {
"parent": {
"name": "buyTokens",
"type": "function",
"source_mapping": {
"lines": [
698,
699,
700,
701,
702,
703,
704,
705,
706,
707,
708,
709,
710,
711,
712,
713,
714,
715,
716,
717,
718,
719,
720,
721,
722,
723,
724,
725,
726,
727,
728
],
"start": 27288,
"length": 884,
"ending_column": 22,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 63,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"type_specific_fields": {
"parent": {
"name": "Crowdsale",
"type": "contract",
"source_mapping": {
"lines": [
570,
571,
572,
573,
574,
575,
576,
577,
578,
579,
580,
581,
582,
583,
584,
585,
586,
587,
588,
589,
590,
591,
592,
593,
594,
595,
596,
597,
598,
599,
600,
601,
602,
603,
604,
605,
606,
607,
608,
609,
610,
611,
612,
613,
614,
615,
616,
617,
618,
619,
620,
621,
622,
623,
624,
625,
626,
627,
628,
629,
630,
631,
632,
633,
634,
635,
636,
637,
638,
639,
640,
641,
642,
643,
644,
645,
646,
647,
648,
649,
650,
651,
652,
653,
654,
655,
656,
657,
658,
659,
660,
661,
662,
663,
664,
665,
666,
667,
668,
669,
670,
671,
672,
673,
674,
675,
676,
677,
678,
679,
680,
681,
682,
683,
684,
685,
686,
687,
688,
689,
690,
691,
692,
693,
694,
695,
696,
697,
698,
699,
700,
701,
702,
703,
704,
705,
706,
707,
708,
709,
710,
711,
712,
713,
714,
715,
716,
717,
718,
719,
720,
721,
722,
723,
724,
725,
726,
727,
728,
729,
730,
731,
732,
733,
734,
735,
736,
737,
738,
739,
740,
741,
742,
743,
744,
745,
746,
747,
748,
749,
750,
751,
752,
753,
754,
755,
756,
757,
758,
759,
760,
761,
762,
763,
764,
765,
766,
767,
768,
769,
770,
771,
772,
773,
774,
775,
776,
777,
778,
779,
780,
781,
782,
783,
784,
785,
786,
787,
788,
789,
790,
791,
792,
793,
794,
795,
796,
797,
798,
799,
800,
801,
802,
803,
804,
805,
806,
807,
808,
809,
810,
811,
812,
813,
814,
815,
816,
817,
818,
819,
820,
821,
822,
823,
824,
825,
826,
827,
828,
829,
830,
831,
832,
833,
834,
835,
836,
837,
838,
839,
840,
841,
842,
843,
844,
845,
846,
847,
848,
849,
850,
851,
852,
853,
854,
855,
856,
857,
858,
859,
860,
861,
862,
863,
864,
865,
866,
867,
868,
869,
870
],
"start": 21490,
"length": 12690,
"ending_column": 35,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 35,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
}
},
"signature": "buyTokens(address)"
}
}
}
}
],
"locations": [
{
"file": "contracts/Contract.sol",
"name": "buyTokens",
"type": "function",
"lines": [
698,
699,
700,
701,
702,
703,
704,
705,
706,
707,
708,
709,
710,
711,
712,
713,
714,
715,
716,
717,
718,
719,
720,
721,
722,
723,
724,
725,
726,
727,
728
]
},
{
"file": "contracts/Contract.sol",
"name": "_processPurchase(beneficiary,tokens)",
"type": "node",
"lines": [
718,
719,
720
]
},
{
"file": "contracts/Contract.sol",
"name": "_token.safeTransfer(beneficiary,tokenAmount)",
"type": "node",
"lines": [
766
]
},
{
"file": "contracts/Contract.sol",
"name": "(success,returndata) = address(token).call(data)",
"type": "node",
"lines": [
402,
403
]
},
{
"file": "contracts/Contract.sol",
"name": "_forwardFunds()",
"type": "node",
"lines": [
722,
723
]
},
{
"file": "contracts/Contract.sol",
"name": "_walletA.transfer(walletAmountA)",
"type": "node",
"lines": [
802
]
},
{
"file": "contracts/Contract.sol",
"name": "_walletB.transfer(walletAmountB)",
"type": "node",
"lines": [
807
]
},
{
"file": "contracts/Contract.sol",
"name": "_walletC.transfer(walletAmountC)",
"type": "node",
"lines": [
810
]
},
{
"file": "contracts/Contract.sol",
"name": "roundDetails[currentRound].amountReached = roundDetails[currentRound].amountReached.add(weiAmount)",
"type": "node",
"lines": [
725,
726,
727,
728
]
}
],
"description": "Reentrancy in Crowdsale.buyTokens(address) (contracts/Contract.sol#698-728):\n\tExternal calls:\n\t- _processPurchase(beneficiary,tokens) (contracts/Contract.sol#718-720)\n\t\t- _token.safeTransfer(beneficiary,tokenAmount) (contracts/Contract.sol#766)\n\t\t- (success,returndata) = address(token).call(data) (contracts/Contract.sol#402-403)\n\tExternal calls sending eth:\n\t- _forwardFunds() (contracts/Contract.sol#722-723)\n\t\t- _walletA.transfer(walletAmountA) (contracts/Contract.sol#802)\n\t\t- _walletB.transfer(walletAmountB) (contracts/Contract.sol#807)\n\t\t- _walletC.transfer(walletAmountC) (contracts/Contract.sol#810)\n\tState variables written after the call(s):\n\t- roundDetails[currentRound].amountReached = roundDetails[currentRound].amountReached.add(weiAmount) (contracts/Contract.sol#725-728)\n\tCrowdsale.roundDetails (contracts/Contract.sol#581-583) can be used in cross function reentrancies:\n\t- Crowdsale._checkRoundValidity(address,uint256) (contracts/Contract.sol#633-644)\n\t- Crowdsale._updateRound() (contracts/Contract.sol#601-633)\n\t- Crowdsale.addRound(uint256,uint256,uint256,uint256,uint256) (contracts/Contract.sol#821-826)\n\t- Crowdsale.buyTokens(address) (contracts/Contract.sol#698-728)\n\t- Crowdsale.constructor(IERC20,address,uint256,address,uint256,address,uint256) (contracts/Contract.sol#661-676)\n\t- Crowdsale.roundDetails (contracts/Contract.sol#581-583)"
}
|
| high | other | slither | Crowdsale.withdrawTokens(IERC20,address) (contracts/Contract.sol#854-862) ignores return value by token_.transfer(beneficiary_,balance) (contracts/Contract.sol#859-862) | 85 | no | — |
viewevidence_json{
"impact": "High",
"detector": "unchecked-transfer",
"elements": [
{
"name": "withdrawTokens",
"type": "function",
"source_mapping": {
"lines": [
854,
855,
856,
857,
858,
859,
860,
861,
862
],
"start": 33688,
"length": 256,
"ending_column": 22,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 24,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"type_specific_fields": {
"parent": {
"name": "Crowdsale",
"type": "contract",
"source_mapping": {
"lines": [
570,
571,
572,
573,
574,
575,
576,
577,
578,
579,
580,
581,
582,
583,
584,
585,
586,
587,
588,
589,
590,
591,
592,
593,
594,
595,
596,
597,
598,
599,
600,
601,
602,
603,
604,
605,
606,
607,
608,
609,
610,
611,
612,
613,
614,
615,
616,
617,
618,
619,
620,
621,
622,
623,
624,
625,
626,
627,
628,
629,
630,
631,
632,
633,
634,
635,
636,
637,
638,
639,
640,
641,
642,
643,
644,
645,
646,
647,
648,
649,
650,
651,
652,
653,
654,
655,
656,
657,
658,
659,
660,
661,
662,
663,
664,
665,
666,
667,
668,
669,
670,
671,
672,
673,
674,
675,
676,
677,
678,
679,
680,
681,
682,
683,
684,
685,
686,
687,
688,
689,
690,
691,
692,
693,
694,
695,
696,
697,
698,
699,
700,
701,
702,
703,
704,
705,
706,
707,
708,
709,
710,
711,
712,
713,
714,
715,
716,
717,
718,
719,
720,
721,
722,
723,
724,
725,
726,
727,
728,
729,
730,
731,
732,
733,
734,
735,
736,
737,
738,
739,
740,
741,
742,
743,
744,
745,
746,
747,
748,
749,
750,
751,
752,
753,
754,
755,
756,
757,
758,
759,
760,
761,
762,
763,
764,
765,
766,
767,
768,
769,
770,
771,
772,
773,
774,
775,
776,
777,
778,
779,
780,
781,
782,
783,
784,
785,
786,
787,
788,
789,
790,
791,
792,
793,
794,
795,
796,
797,
798,
799,
800,
801,
802,
803,
804,
805,
806,
807,
808,
809,
810,
811,
812,
813,
814,
815,
816,
817,
818,
819,
820,
821,
822,
823,
824,
825,
826,
827,
828,
829,
830,
831,
832,
833,
834,
835,
836,
837,
838,
839,
840,
841,
842,
843,
844,
845,
846,
847,
848,
849,
850,
851,
852,
853,
854,
855,
856,
857,
858,
859,
860,
861,
862,
863,
864,
865,
866,
867,
868,
869,
870
],
"start": 21490,
"length": 12690,
"ending_column": 35,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 35,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
}
},
"signature": "withdrawTokens(IERC20,address)"
}
},
{
"name": "token_.transfer(beneficiary_,balance)",
"type": "node",
"source_mapping": {
"lines": [
859,
860,
861,
862
],
"start": 33899,
"length": 38,
"ending_column": 15,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 37,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"type_specific_fields": {
"parent": {
"name": "withdrawTokens",
"type": "function",
"source_mapping": {
"lines": [
854,
855,
856,
857,
858,
859,
860,
861,
862
],
"start": 33688,
"length": 256,
"ending_column": 22,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 24,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
},
"type_specific_fields": {
"parent": {
"name": "Crowdsale",
"type": "contract",
"source_mapping": {
"lines": [
570,
571,
572,
573,
574,
575,
576,
577,
578,
579,
580,
581,
582,
583,
584,
585,
586,
587,
588,
589,
590,
591,
592,
593,
594,
595,
596,
597,
598,
599,
600,
601,
602,
603,
604,
605,
606,
607,
608,
609,
610,
611,
612,
613,
614,
615,
616,
617,
618,
619,
620,
621,
622,
623,
624,
625,
626,
627,
628,
629,
630,
631,
632,
633,
634,
635,
636,
637,
638,
639,
640,
641,
642,
643,
644,
645,
646,
647,
648,
649,
650,
651,
652,
653,
654,
655,
656,
657,
658,
659,
660,
661,
662,
663,
664,
665,
666,
667,
668,
669,
670,
671,
672,
673,
674,
675,
676,
677,
678,
679,
680,
681,
682,
683,
684,
685,
686,
687,
688,
689,
690,
691,
692,
693,
694,
695,
696,
697,
698,
699,
700,
701,
702,
703,
704,
705,
706,
707,
708,
709,
710,
711,
712,
713,
714,
715,
716,
717,
718,
719,
720,
721,
722,
723,
724,
725,
726,
727,
728,
729,
730,
731,
732,
733,
734,
735,
736,
737,
738,
739,
740,
741,
742,
743,
744,
745,
746,
747,
748,
749,
750,
751,
752,
753,
754,
755,
756,
757,
758,
759,
760,
761,
762,
763,
764,
765,
766,
767,
768,
769,
770,
771,
772,
773,
774,
775,
776,
777,
778,
779,
780,
781,
782,
783,
784,
785,
786,
787,
788,
789,
790,
791,
792,
793,
794,
795,
796,
797,
798,
799,
800,
801,
802,
803,
804,
805,
806,
807,
808,
809,
810,
811,
812,
813,
814,
815,
816,
817,
818,
819,
820,
821,
822,
823,
824,
825,
826,
827,
828,
829,
830,
831,
832,
833,
834,
835,
836,
837,
838,
839,
840,
841,
842,
843,
844,
845,
846,
847,
848,
849,
850,
851,
852,
853,
854,
855,
856,
857,
858,
859,
860,
861,
862,
863,
864,
865,
866,
867,
868,
869,
870
],
"start": 21490,
"length": 12690,
"ending_column": 35,
"is_dependency": false,
"filename_short": "contracts/Contract.sol",
"starting_column": 35,
"filename_absolute": "/tmp/slither-y5vnqpje/contracts/Contract.sol",
"filename_relative": "contracts/Contract.sol"
}
},
"signature": "withdrawTokens(IERC20,address)"
}
}
}
}
],
"locations": [
{
"file": "contracts/Contract.sol",
"name": "withdrawTokens",
"type": "function",
"lines": [
854,
855,
856,
857,
858,
859,
860,
861,
862
]
},
{
"file": "contracts/Contract.sol",
"name": "token_.transfer(beneficiary_,balance)",
"type": "node",
"lines": [
859,
860,
861,
862
]
}
],
"description": "Crowdsale.withdrawTokens(IERC20,address) (contracts/Contract.sol#854-862) ignores return value by token_.transfer(beneficiary_,balance) (contracts/Contract.sol#859-862)"
}
|
| medium | other | codex | Per-address round contribution caps are unenforced because contributor totals are never updated | 75 | no | — |
viewevidence_json{
"evidence": "The limit check reads `contributors[_contributor]` at line 648, but `_updatePurchasingState()` is empty and no other code writes to the `contributors` mapping.",
"locations": [
"contracts/Contract.sol:648",
"contracts/Contract.sol:740",
"contracts/Contract.sol:801"
],
"recommendation": "Update `roundDetails[currentRound].contributors[beneficiary or msg.sender]` during the purchase flow before external interactions, and add tests that assert cumulative per-round limits across multiple transactions.",
"exploit_scenario": "A buyer can split a large purchase into many transactions and exceed the advertised `maxContibution` for the round. `_checkRoundValidity()` checks `roundDetails[currentRound].contributors[_contributor] + _amount`, but that mapping is never incremented anywhere in the purchase flow, so each call is validated as if the sender had contributed `0` previously."
}
|
| medium | reentrancy | codex | buyTokens performs external token delivery before round accounting and lacks the advertised reentrancy guard | 75 | no | — |
viewevidence_json{
"evidence": "The function comment says `buyTokens` has a non-reentrancy guard, but no `nonReentrant` modifier is present. `_processPurchase()` calls `_token.safeTransfer(...)` before `amountReached` is incremented at line 746.",
"locations": [
"contracts/Contract.sol:721",
"contracts/Contract.sol:725",
"contracts/Contract.sol:737",
"contracts/Contract.sol:746",
"contracts/Contract.sol:781"
],
"recommendation": "Mark `buyTokens` as `nonReentrant` and move round accounting updates ahead of `_processPurchase()` so all cap checks observe committed state before any external call.",
"exploit_scenario": "If the sale token is ERC777-like or otherwise invokes a callback during `transfer`, a contract beneficiary can reenter `buyTokens` from that callback with additional ETH. Because `roundDetails[currentRound].amountReached` and the contributor mapping are only updated after `_deliverTokens`, the nested call sees stale round state and can bypass round-cap and per-address-limit checks within the same transaction."
}
|