diff --git a/README.md b/README.md index 98ba1b7..495c1be 100644 --- a/README.md +++ b/README.md @@ -174,6 +174,11 @@ The generated signatures will be uploaded to your pinata account. Currently in o * DepositAndPlaceOrder: 0x4bAbb4b89ed7180aeF95F872f621afEE724F0344 * AllowListOffChainManaged: 0xE0AD16EB7Ea467C694E6cFdd5E7D61FE850e8B53 +* Binance Smart Chain Testnet: + * EasyAuction: 0x231F3Fd7c3E3C9a2c8A03B72132c31241DF0a26C + * DepositAndPlaceOrder: 0x14082EDeFCa073578d2C16E8fB42967bEc188E59 + * AllowListOffChainManaged: 0xE0AD16EB7Ea467C694E6cFdd5E7D61FE850e8B53 + * Fuji: * EasyAuction: 0xa5cd8D8effACB7Ad861e3797404924199D1463a5 * DepositAndPlaceOrder: 0x39cbA0cC28EE67EAa8134C0e80a061c13EBC3603 diff --git a/deployments/binancesmartchaintestnet/.chainId b/deployments/binancesmartchaintestnet/.chainId new file mode 100644 index 0000000..c4fbb1c --- /dev/null +++ b/deployments/binancesmartchaintestnet/.chainId @@ -0,0 +1 @@ +97 \ No newline at end of file diff --git a/deployments/binancesmartchaintestnet/AllowListOffChainManaged.json b/deployments/binancesmartchaintestnet/AllowListOffChainManaged.json new file mode 100644 index 0000000..0fe494f --- /dev/null +++ b/deployments/binancesmartchaintestnet/AllowListOffChainManaged.json @@ -0,0 +1,120 @@ +{ + "address": "0xE0AD16EB7Ea467C694E6cFdd5E7D61FE850e8B53", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "domainSeparator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "name": "isAllowed", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "allower", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "name": "isAllowedBy", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "args": [], + "numDeployments": 1, + "solcInputHash": "a81c49f8848cbbe2b3d955ebaff2de99", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"domainSeparator\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"name\":\"isAllowed\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"allower\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"callData\",\"type\":\"bytes\"}],\"name\":\"isAllowedBy\",\"outputs\":[{\"internalType\":\"bytes4\",\"name\":\"\",\"type\":\"bytes4\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"DOMAIN_NAME\":{\"details\":\"The EIP-712 domain name used for computing the domain separator.\"},\"DOMAIN_TYPE_HASH\":{\"details\":\"The EIP-712 domain type hash used for computing the domain separator.\"},\"DOMAIN_VERSION\":{\"details\":\"The EIP-712 domain version used for computing the domain separator.\"},\"domainSeparator\":{\"details\":\"The domain separator used for signing orders that gets mixed in making signatures for different domains incompatible. This domain separator is computed following the EIP-712 standard and has replay protection mixed in so that signed orders are only valid for specific GPv2 contracts.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/allowListExamples/AllowListOffChainManaged.sol\":\"AllowListOffChainManaged\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(_owner == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0xf7c39c7e6d06ed3bda90cfefbcbf2ddc32c599c3d6721746546ad64946efccaa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute\\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\\n }\\n}\\n\",\"keccak256\":\"0x363bd3b45201f07c9b71c2edc96533468cf14a3d029fabd82fddceb1eb3ebd9c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x3b21f2c8d626de3b9925ae33e972d8bf5c8b1bffb3f4ee94daeed7d0679036e6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x5f02220344881ce43204ae4a6281145a67bc52c2bb1290a791857df3d19d78f5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf12dfbe97e6276980b83d2830bb0eb75e0cf4f3e626c2471137f82158ae6a0fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa6a15ddddcbf29d2922a1e0d4151b5d2d33da24b93cc9ebc12390e0d855532f8\",\"license\":\"MIT\"},\"contracts/EasyAuction.sol\":{\"content\":\"pragma solidity >=0.6.8;\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"./libraries/IterableOrderedOrderSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"./libraries/IdToAddressBiMap.sol\\\";\\nimport \\\"./libraries/SafeCast.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"./interfaces/AllowListVerifier.sol\\\";\\n\\ncontract EasyAuction is Ownable {\\n using SafeERC20 for IERC20;\\n using SafeMath for uint64;\\n using SafeMath for uint96;\\n using SafeMath for uint256;\\n using SafeCast for uint256;\\n using IterableOrderedOrderSet for IterableOrderedOrderSet.Data;\\n using IterableOrderedOrderSet for bytes32;\\n using IdToAddressBiMap for IdToAddressBiMap.Data;\\n\\n modifier atStageOrderPlacement(uint256 auctionId) {\\n require(\\n block.timestamp < auctionData[auctionId].auctionEndDate,\\n \\\"no longer in order placement phase\\\"\\n );\\n _;\\n }\\n\\n modifier atStageOrderPlacementAndCancelation(uint256 auctionId) {\\n require(\\n block.timestamp < auctionData[auctionId].orderCancellationEndDate,\\n \\\"no longer in order placement and cancelation phase\\\"\\n );\\n _;\\n }\\n\\n modifier atStageSolutionSubmission(uint256 auctionId) {\\n {\\n uint256 auctionEndDate = auctionData[auctionId].auctionEndDate;\\n require(\\n auctionEndDate != 0 &&\\n block.timestamp >= auctionEndDate &&\\n auctionData[auctionId].clearingPriceOrder == bytes32(0),\\n \\\"Auction not in solution submission phase\\\"\\n );\\n }\\n _;\\n }\\n\\n modifier atStageFinished(uint256 auctionId) {\\n require(\\n auctionData[auctionId].clearingPriceOrder != bytes32(0),\\n \\\"Auction not yet finished\\\"\\n );\\n _;\\n }\\n\\n event NewSellOrder(\\n uint256 indexed auctionId,\\n uint64 indexed userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n );\\n event CancellationSellOrder(\\n uint256 indexed auctionId,\\n uint64 indexed userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n );\\n event ClaimedFromOrder(\\n uint256 indexed auctionId,\\n uint64 indexed userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n );\\n event NewUser(uint64 indexed userId, address indexed userAddress);\\n event NewAuction(\\n uint256 indexed auctionId,\\n IERC20 indexed _auctioningToken,\\n IERC20 indexed _biddingToken,\\n uint256 orderCancellationEndDate,\\n uint256 auctionEndDate,\\n uint64 userId,\\n uint96 _auctionedSellAmount,\\n uint96 _minBuyAmount,\\n uint256 minimumBiddingAmountPerOrder,\\n uint256 minFundingThreshold,\\n address allowListContract,\\n bytes allowListData\\n );\\n event AuctionCleared(\\n uint256 indexed auctionId,\\n uint96 soldAuctioningTokens,\\n uint96 soldBiddingTokens,\\n bytes32 clearingPriceOrder\\n );\\n event UserRegistration(address indexed user, uint64 userId);\\n\\n struct AuctionData {\\n IERC20 auctioningToken;\\n IERC20 biddingToken;\\n uint256 orderCancellationEndDate;\\n uint256 auctionEndDate;\\n bytes32 initialAuctionOrder;\\n uint256 minimumBiddingAmountPerOrder;\\n uint256 interimSumBidAmount;\\n bytes32 interimOrder;\\n bytes32 clearingPriceOrder;\\n uint96 volumeClearingPriceOrder;\\n bool minFundingThresholdNotReached;\\n bool isAtomicClosureAllowed;\\n uint256 feeNumerator;\\n uint256 minFundingThreshold;\\n }\\n mapping(uint256 => IterableOrderedOrderSet.Data) internal sellOrders;\\n mapping(uint256 => AuctionData) public auctionData;\\n mapping(uint256 => address) public auctionAccessManager;\\n mapping(uint256 => bytes) public auctionAccessData;\\n\\n IdToAddressBiMap.Data private registeredUsers;\\n uint64 public numUsers;\\n uint256 public auctionCounter;\\n\\n constructor() public Ownable() {}\\n\\n uint256 public feeNumerator = 0;\\n uint256 public constant FEE_DENOMINATOR = 1000;\\n uint64 public feeReceiverUserId = 1;\\n\\n function setFeeParameters(\\n uint256 newFeeNumerator,\\n address newfeeReceiverAddress\\n ) public onlyOwner() {\\n require(\\n newFeeNumerator <= 15,\\n \\\"Fee is not allowed to be set higher than 1.5%\\\"\\n );\\n // caution: for currently running auctions, the feeReceiverUserId is changing as well.\\n feeReceiverUserId = getUserId(newfeeReceiverAddress);\\n feeNumerator = newFeeNumerator;\\n }\\n\\n // @dev: function to intiate a new auction\\n // Warning: In case the auction is expected to raise more than\\n // 2^96 units of the biddingToken, don't start the auction, as\\n // it will not be settlable. This corresponds to about 79\\n // billion DAI.\\n //\\n // Prices between biddingToken and auctioningToken are expressed by a\\n // fraction whose components are stored as uint96.\\n function initiateAuction(\\n IERC20 _auctioningToken,\\n IERC20 _biddingToken,\\n uint256 orderCancellationEndDate,\\n uint256 auctionEndDate,\\n uint96 _auctionedSellAmount,\\n uint96 _minBuyAmount,\\n uint256 minimumBiddingAmountPerOrder,\\n uint256 minFundingThreshold,\\n bool isAtomicClosureAllowed,\\n address accessManagerContract,\\n bytes memory accessManagerContractData\\n ) public returns (uint256) {\\n // withdraws sellAmount + fees\\n _auctioningToken.safeTransferFrom(\\n msg.sender,\\n address(this),\\n _auctionedSellAmount.mul(FEE_DENOMINATOR.add(feeNumerator)).div(\\n FEE_DENOMINATOR\\n ) //[0]\\n );\\n require(_auctionedSellAmount > 0, \\\"cannot auction zero tokens\\\");\\n require(_minBuyAmount > 0, \\\"tokens cannot be auctioned for free\\\");\\n require(\\n minimumBiddingAmountPerOrder > 0,\\n \\\"minimumBiddingAmountPerOrder is not allowed to be zero\\\"\\n );\\n require(\\n orderCancellationEndDate <= auctionEndDate,\\n \\\"time periods are not configured correctly\\\"\\n );\\n require(\\n auctionEndDate > block.timestamp,\\n \\\"auction end date must be in the future\\\"\\n );\\n auctionCounter = auctionCounter.add(1);\\n sellOrders[auctionCounter].initializeEmptyList();\\n uint64 userId = getUserId(msg.sender);\\n auctionData[auctionCounter] = AuctionData(\\n _auctioningToken,\\n _biddingToken,\\n orderCancellationEndDate,\\n auctionEndDate,\\n IterableOrderedOrderSet.encodeOrder(\\n userId,\\n _minBuyAmount,\\n _auctionedSellAmount\\n ),\\n minimumBiddingAmountPerOrder,\\n 0,\\n IterableOrderedOrderSet.QUEUE_START,\\n bytes32(0),\\n 0,\\n false,\\n isAtomicClosureAllowed,\\n feeNumerator,\\n minFundingThreshold\\n );\\n auctionAccessManager[auctionCounter] = accessManagerContract;\\n auctionAccessData[auctionCounter] = accessManagerContractData;\\n emit NewAuction(\\n auctionCounter,\\n _auctioningToken,\\n _biddingToken,\\n orderCancellationEndDate,\\n auctionEndDate,\\n userId,\\n _auctionedSellAmount,\\n _minBuyAmount,\\n minimumBiddingAmountPerOrder,\\n minFundingThreshold,\\n accessManagerContract,\\n accessManagerContractData\\n );\\n return auctionCounter;\\n }\\n\\n function placeSellOrders(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmounts,\\n uint96[] memory _sellAmounts,\\n bytes32[] memory _prevSellOrders,\\n bytes calldata allowListCallData\\n ) external atStageOrderPlacement(auctionId) returns (uint64 userId) {\\n return\\n _placeSellOrders(\\n auctionId,\\n _minBuyAmounts,\\n _sellAmounts,\\n _prevSellOrders,\\n allowListCallData,\\n msg.sender\\n );\\n }\\n\\n function placeSellOrdersOnBehalf(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmounts,\\n uint96[] memory _sellAmounts,\\n bytes32[] memory _prevSellOrders,\\n bytes calldata allowListCallData,\\n address orderSubmitter\\n ) external atStageOrderPlacement(auctionId) returns (uint64 userId) {\\n return\\n _placeSellOrders(\\n auctionId,\\n _minBuyAmounts,\\n _sellAmounts,\\n _prevSellOrders,\\n allowListCallData,\\n orderSubmitter\\n );\\n }\\n\\n function _placeSellOrders(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmounts,\\n uint96[] memory _sellAmounts,\\n bytes32[] memory _prevSellOrders,\\n bytes calldata allowListCallData,\\n address orderSubmitter\\n ) internal returns (uint64 userId) {\\n {\\n address allowListManager = auctionAccessManager[auctionId];\\n if (allowListManager != address(0)) {\\n require(\\n AllowListVerifier(allowListManager).isAllowed(\\n orderSubmitter,\\n auctionId,\\n allowListCallData\\n ) == AllowListVerifierHelper.MAGICVALUE,\\n \\\"user not allowed to place order\\\"\\n );\\n }\\n }\\n {\\n (\\n ,\\n uint96 buyAmountOfInitialAuctionOrder,\\n uint96 sellAmountOfInitialAuctionOrder\\n ) = auctionData[auctionId].initialAuctionOrder.decodeOrder();\\n for (uint256 i = 0; i < _minBuyAmounts.length; i++) {\\n require(\\n _minBuyAmounts[i].mul(buyAmountOfInitialAuctionOrder) <\\n sellAmountOfInitialAuctionOrder.mul(_sellAmounts[i]),\\n \\\"limit price not better than mimimal offer\\\"\\n );\\n }\\n }\\n uint256 sumOfSellAmounts = 0;\\n userId = getUserId(orderSubmitter);\\n uint256 minimumBiddingAmountPerOrder =\\n auctionData[auctionId].minimumBiddingAmountPerOrder;\\n for (uint256 i = 0; i < _minBuyAmounts.length; i++) {\\n require(\\n _minBuyAmounts[i] > 0,\\n \\\"_minBuyAmounts must be greater than 0\\\"\\n );\\n // orders should have a minimum bid size in order to limit the gas\\n // required to compute the final price of the auction.\\n require(\\n _sellAmounts[i] > minimumBiddingAmountPerOrder,\\n \\\"order too small\\\"\\n );\\n if (\\n sellOrders[auctionId].insert(\\n IterableOrderedOrderSet.encodeOrder(\\n userId,\\n _minBuyAmounts[i],\\n _sellAmounts[i]\\n ),\\n _prevSellOrders[i]\\n )\\n ) {\\n sumOfSellAmounts = sumOfSellAmounts.add(_sellAmounts[i]);\\n emit NewSellOrder(\\n auctionId,\\n userId,\\n _minBuyAmounts[i],\\n _sellAmounts[i]\\n );\\n }\\n }\\n auctionData[auctionId].biddingToken.safeTransferFrom(\\n msg.sender,\\n address(this),\\n sumOfSellAmounts\\n ); //[1]\\n }\\n\\n function cancelSellOrders(uint256 auctionId, bytes32[] memory _sellOrders)\\n public\\n atStageOrderPlacementAndCancelation(auctionId)\\n {\\n uint64 userId = getUserId(msg.sender);\\n uint256 claimableAmount = 0;\\n for (uint256 i = 0; i < _sellOrders.length; i++) {\\n // Note: we keep the back pointer of the deleted element so that\\n // it can be used as a reference point to insert a new node.\\n bool success =\\n sellOrders[auctionId].removeKeepHistory(_sellOrders[i]);\\n if (success) {\\n (\\n uint64 userIdOfIter,\\n uint96 buyAmountOfIter,\\n uint96 sellAmountOfIter\\n ) = _sellOrders[i].decodeOrder();\\n require(\\n userIdOfIter == userId,\\n \\\"Only the user can cancel his orders\\\"\\n );\\n claimableAmount = claimableAmount.add(sellAmountOfIter);\\n emit CancellationSellOrder(\\n auctionId,\\n userId,\\n buyAmountOfIter,\\n sellAmountOfIter\\n );\\n }\\n }\\n auctionData[auctionId].biddingToken.safeTransfer(\\n msg.sender,\\n claimableAmount\\n ); //[2]\\n }\\n\\n function precalculateSellAmountSum(\\n uint256 auctionId,\\n uint256 iterationSteps\\n ) public atStageSolutionSubmission(auctionId) {\\n (, , uint96 auctioneerSellAmount) =\\n auctionData[auctionId].initialAuctionOrder.decodeOrder();\\n uint256 sumBidAmount = auctionData[auctionId].interimSumBidAmount;\\n bytes32 iterOrder = auctionData[auctionId].interimOrder;\\n\\n for (uint256 i = 0; i < iterationSteps; i++) {\\n iterOrder = sellOrders[auctionId].next(iterOrder);\\n (, , uint96 sellAmountOfIter) = iterOrder.decodeOrder();\\n sumBidAmount = sumBidAmount.add(sellAmountOfIter);\\n }\\n\\n require(\\n iterOrder != IterableOrderedOrderSet.QUEUE_END,\\n \\\"reached end of order list\\\"\\n );\\n\\n // it is checked that not too many iteration steps were taken:\\n // require that the sum of SellAmounts times the price of the last order\\n // is not more than initially sold amount\\n (, uint96 buyAmountOfIter, uint96 sellAmountOfIter) =\\n iterOrder.decodeOrder();\\n require(\\n sumBidAmount.mul(buyAmountOfIter) <\\n auctioneerSellAmount.mul(sellAmountOfIter),\\n \\\"too many orders summed up\\\"\\n );\\n\\n auctionData[auctionId].interimSumBidAmount = sumBidAmount;\\n auctionData[auctionId].interimOrder = iterOrder;\\n }\\n\\n function settleAuctionAtomically(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmount,\\n uint96[] memory _sellAmount,\\n bytes32[] memory _prevSellOrder,\\n bytes calldata allowListCallData\\n ) public atStageSolutionSubmission(auctionId) {\\n require(\\n auctionData[auctionId].isAtomicClosureAllowed,\\n \\\"not allowed to settle auction atomically\\\"\\n );\\n require(\\n _minBuyAmount.length == 1 && _sellAmount.length == 1,\\n \\\"Only one order can be placed atomically\\\"\\n );\\n uint64 userId = getUserId(msg.sender);\\n require(\\n auctionData[auctionId].interimOrder.smallerThan(\\n IterableOrderedOrderSet.encodeOrder(\\n userId,\\n _minBuyAmount[0],\\n _sellAmount[0]\\n )\\n ),\\n \\\"precalculateSellAmountSum is already too advanced\\\"\\n );\\n _placeSellOrders(\\n auctionId,\\n _minBuyAmount,\\n _sellAmount,\\n _prevSellOrder,\\n allowListCallData,\\n msg.sender\\n );\\n settleAuction(auctionId);\\n }\\n\\n // @dev function settling the auction and calculating the price\\n function settleAuction(uint256 auctionId)\\n public\\n atStageSolutionSubmission(auctionId)\\n returns (bytes32 clearingOrder)\\n {\\n (\\n uint64 auctioneerId,\\n uint96 minAuctionedBuyAmount,\\n uint96 fullAuctionedAmount\\n ) = auctionData[auctionId].initialAuctionOrder.decodeOrder();\\n\\n uint256 currentBidSum = auctionData[auctionId].interimSumBidAmount;\\n bytes32 currentOrder = auctionData[auctionId].interimOrder;\\n uint256 buyAmountOfIter;\\n uint256 sellAmountOfIter;\\n uint96 fillVolumeOfAuctioneerOrder = fullAuctionedAmount;\\n // Sum order up, until fullAuctionedAmount is fully bought or queue end is reached\\n do {\\n bytes32 nextOrder = sellOrders[auctionId].next(currentOrder);\\n if (nextOrder == IterableOrderedOrderSet.QUEUE_END) {\\n break;\\n }\\n currentOrder = nextOrder;\\n (, buyAmountOfIter, sellAmountOfIter) = currentOrder.decodeOrder();\\n currentBidSum = currentBidSum.add(sellAmountOfIter);\\n } while (\\n currentBidSum.mul(buyAmountOfIter) <\\n fullAuctionedAmount.mul(sellAmountOfIter)\\n );\\n\\n if (\\n currentBidSum > 0 &&\\n currentBidSum.mul(buyAmountOfIter) >=\\n fullAuctionedAmount.mul(sellAmountOfIter)\\n ) {\\n // All considered/summed orders are sufficient to close the auction fully\\n // at price between current and previous orders.\\n uint256 uncoveredBids =\\n currentBidSum.sub(\\n fullAuctionedAmount.mul(sellAmountOfIter).div(\\n buyAmountOfIter\\n )\\n );\\n\\n if (sellAmountOfIter >= uncoveredBids) {\\n //[13]\\n // Auction fully filled via partial match of currentOrder\\n uint256 sellAmountClearingOrder =\\n sellAmountOfIter.sub(uncoveredBids);\\n auctionData[auctionId]\\n .volumeClearingPriceOrder = sellAmountClearingOrder\\n .toUint96();\\n currentBidSum = currentBidSum.sub(uncoveredBids);\\n clearingOrder = currentOrder;\\n } else {\\n //[14]\\n // Auction fully filled via price strictly between currentOrder and the order\\n // immediately before. For a proof, see the security-considerations.md\\n currentBidSum = currentBidSum.sub(sellAmountOfIter);\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\n 0,\\n fullAuctionedAmount,\\n currentBidSum.toUint96()\\n );\\n }\\n } else {\\n // All considered/summed orders are not sufficient to close the auction fully at price of last order //[18]\\n // Either a higher price must be used or auction is only partially filled\\n\\n if (currentBidSum > minAuctionedBuyAmount) {\\n //[15]\\n // Price higher than last order would fill the auction\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\n 0,\\n fullAuctionedAmount,\\n currentBidSum.toUint96()\\n );\\n } else {\\n //[16]\\n // Even at the initial auction price, the auction is partially filled\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\n 0,\\n fullAuctionedAmount,\\n minAuctionedBuyAmount\\n );\\n fillVolumeOfAuctioneerOrder = currentBidSum\\n .mul(fullAuctionedAmount)\\n .div(minAuctionedBuyAmount)\\n .toUint96();\\n }\\n }\\n auctionData[auctionId].clearingPriceOrder = clearingOrder;\\n\\n if (auctionData[auctionId].minFundingThreshold > currentBidSum) {\\n auctionData[auctionId].minFundingThresholdNotReached = true;\\n }\\n processFeesAndAuctioneerFunds(\\n auctionId,\\n fillVolumeOfAuctioneerOrder,\\n auctioneerId,\\n fullAuctionedAmount\\n );\\n emit AuctionCleared(\\n auctionId,\\n fillVolumeOfAuctioneerOrder,\\n uint96(currentBidSum),\\n clearingOrder\\n );\\n // Gas refunds\\n auctionAccessManager[auctionId] = address(0);\\n delete auctionAccessData[auctionId];\\n auctionData[auctionId].initialAuctionOrder = bytes32(0);\\n auctionData[auctionId].interimOrder = bytes32(0);\\n auctionData[auctionId].interimSumBidAmount = uint256(0);\\n auctionData[auctionId].minimumBiddingAmountPerOrder = uint256(0);\\n }\\n\\n function claimFromParticipantOrder(\\n uint256 auctionId,\\n bytes32[] memory orders\\n )\\n public\\n atStageFinished(auctionId)\\n returns (\\n uint256 sumAuctioningTokenAmount,\\n uint256 sumBiddingTokenAmount\\n )\\n {\\n for (uint256 i = 0; i < orders.length; i++) {\\n // Note: we don't need to keep any information about the node since\\n // no new elements need to be inserted.\\n require(\\n sellOrders[auctionId].remove(orders[i]),\\n \\\"order is no longer claimable\\\"\\n );\\n }\\n AuctionData memory auction = auctionData[auctionId];\\n (, uint96 priceNumerator, uint96 priceDenominator) =\\n auction.clearingPriceOrder.decodeOrder();\\n (uint64 userId, , ) = orders[0].decodeOrder();\\n bool minFundingThresholdNotReached =\\n auctionData[auctionId].minFundingThresholdNotReached;\\n for (uint256 i = 0; i < orders.length; i++) {\\n (uint64 userIdOrder, uint96 buyAmount, uint96 sellAmount) =\\n orders[i].decodeOrder();\\n require(\\n userIdOrder == userId,\\n \\\"only allowed to claim for same user\\\"\\n );\\n if (minFundingThresholdNotReached) {\\n //[10]\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(sellAmount);\\n } else {\\n //[23]\\n if (orders[i] == auction.clearingPriceOrder) {\\n //[25]\\n sumAuctioningTokenAmount = sumAuctioningTokenAmount.add(\\n auction\\n .volumeClearingPriceOrder\\n .mul(priceNumerator)\\n .div(priceDenominator)\\n );\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(\\n sellAmount.sub(auction.volumeClearingPriceOrder)\\n );\\n } else {\\n if (orders[i].smallerThan(auction.clearingPriceOrder)) {\\n //[17]\\n sumAuctioningTokenAmount = sumAuctioningTokenAmount.add(\\n sellAmount.mul(priceNumerator).div(priceDenominator)\\n );\\n } else {\\n //[24]\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(\\n sellAmount\\n );\\n }\\n }\\n }\\n emit ClaimedFromOrder(auctionId, userId, buyAmount, sellAmount);\\n }\\n sendOutTokens(\\n auctionId,\\n sumAuctioningTokenAmount,\\n sumBiddingTokenAmount,\\n userId\\n ); //[3]\\n }\\n\\n function processFeesAndAuctioneerFunds(\\n uint256 auctionId,\\n uint256 fillVolumeOfAuctioneerOrder,\\n uint64 auctioneerId,\\n uint96 fullAuctionedAmount\\n ) internal {\\n uint256 feeAmount =\\n fullAuctionedAmount.mul(auctionData[auctionId].feeNumerator).div(\\n FEE_DENOMINATOR\\n ); //[20]\\n if (auctionData[auctionId].minFundingThresholdNotReached) {\\n sendOutTokens(\\n auctionId,\\n fullAuctionedAmount.add(feeAmount),\\n 0,\\n auctioneerId\\n ); //[4]\\n } else {\\n //[11]\\n (, uint96 priceNumerator, uint96 priceDenominator) =\\n auctionData[auctionId].clearingPriceOrder.decodeOrder();\\n uint256 unsettledAuctionTokens =\\n fullAuctionedAmount.sub(fillVolumeOfAuctioneerOrder);\\n uint256 auctioningTokenAmount =\\n unsettledAuctionTokens.add(\\n feeAmount.mul(unsettledAuctionTokens).div(\\n fullAuctionedAmount\\n )\\n );\\n uint256 biddingTokenAmount =\\n fillVolumeOfAuctioneerOrder.mul(priceDenominator).div(\\n priceNumerator\\n );\\n sendOutTokens(\\n auctionId,\\n auctioningTokenAmount,\\n biddingTokenAmount,\\n auctioneerId\\n ); //[5]\\n sendOutTokens(\\n auctionId,\\n feeAmount.mul(fillVolumeOfAuctioneerOrder).div(\\n fullAuctionedAmount\\n ),\\n 0,\\n feeReceiverUserId\\n ); //[7]\\n }\\n }\\n\\n function sendOutTokens(\\n uint256 auctionId,\\n uint256 auctioningTokenAmount,\\n uint256 biddingTokenAmount,\\n uint64 userId\\n ) internal {\\n address userAddress = registeredUsers.getAddressAt(userId);\\n if (auctioningTokenAmount > 0) {\\n auctionData[auctionId].auctioningToken.safeTransfer(\\n userAddress,\\n auctioningTokenAmount\\n );\\n }\\n if (biddingTokenAmount > 0) {\\n auctionData[auctionId].biddingToken.safeTransfer(\\n userAddress,\\n biddingTokenAmount\\n );\\n }\\n }\\n\\n function registerUser(address user) public returns (uint64 userId) {\\n numUsers = numUsers.add(1).toUint64();\\n require(\\n registeredUsers.insert(numUsers, user),\\n \\\"User already registered\\\"\\n );\\n userId = numUsers;\\n emit UserRegistration(user, userId);\\n }\\n\\n function getUserId(address user) public returns (uint64 userId) {\\n if (registeredUsers.hasAddress(user)) {\\n userId = registeredUsers.getId(user);\\n } else {\\n userId = registerUser(user);\\n emit NewUser(userId, user);\\n }\\n }\\n\\n function getSecondsRemainingInBatch(uint256 auctionId)\\n public\\n view\\n returns (uint256)\\n {\\n if (auctionData[auctionId].auctionEndDate < block.timestamp) {\\n return 0;\\n }\\n return auctionData[auctionId].auctionEndDate.sub(block.timestamp);\\n }\\n\\n function containsOrder(uint256 auctionId, bytes32 order)\\n public\\n view\\n returns (bool)\\n {\\n return sellOrders[auctionId].contains(order);\\n }\\n}\\n\",\"keccak256\":\"0x4fbbc969d2b2de6d6b9dbb99e16cbf7cdb2dfc0f2b20cac4cbb129a700ab9b69\"},\"contracts/allowListExamples/AllowListOffChainManaged.sol\":{\"content\":\"pragma solidity >=0.6.8;\\nimport \\\"../interfaces/AllowListVerifier.sol\\\";\\nimport \\\"../EasyAuction.sol\\\";\\n\\n// Idea was first mentioned in the blog:\\n// https://medium.com/@PhABC/off-chain-whitelist-with-on-chain-verification-for-ethereum-smart-contracts-1563ca4b8f11\\n\\ncontract AllowListOffChainManaged {\\n /// @dev The EIP-712 domain type hash used for computing the domain\\n /// separator.\\n bytes32 private constant DOMAIN_TYPE_HASH =\\n keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n\\n /// @dev The EIP-712 domain name used for computing the domain separator.\\n bytes32 private constant DOMAIN_NAME = keccak256(\\\"AccessManager\\\");\\n\\n /// @dev The EIP-712 domain version used for computing the domain separator.\\n bytes32 private constant DOMAIN_VERSION = keccak256(\\\"v1\\\");\\n\\n /// @dev The domain separator used for signing orders that gets mixed in\\n /// making signatures for different domains incompatible. This domain\\n /// separator is computed following the EIP-712 standard and has replay\\n /// protection mixed in so that signed orders are only valid for specific\\n /// GPv2 contracts.\\n bytes32 public immutable domainSeparator;\\n\\n constructor() public {\\n // NOTE: Currently, the only way to get the chain ID in solidity is\\n // using assembly.\\n uint256 chainId;\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n chainId := chainid()\\n }\\n\\n domainSeparator = keccak256(\\n abi.encode(\\n DOMAIN_TYPE_HASH,\\n DOMAIN_NAME,\\n DOMAIN_VERSION,\\n chainId,\\n address(this)\\n )\\n );\\n }\\n\\n function isAllowed(\\n address user,\\n uint256 auctionId,\\n bytes calldata callData\\n ) external view returns (bytes4) {\\n return isAllowedBy(user, auctionId, msg.sender, callData);\\n }\\n\\n function isAllowedBy(\\n address user,\\n uint256 auctionId,\\n address allower,\\n bytes calldata callData\\n ) public view returns (bytes4) {\\n uint8 v;\\n bytes32 r;\\n bytes32 s;\\n (v, r, s) = abi.decode(callData, (uint8, bytes32, bytes32));\\n bytes32 hash = keccak256(abi.encode(domainSeparator, user, auctionId));\\n address signer =\\n ecrecover(\\n keccak256(\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\n ),\\n v,\\n r,\\n s\\n );\\n bytes memory allowListData =\\n EasyAuction(allower).auctionAccessData(auctionId);\\n if (abi.decode(allowListData, (address)) == signer) {\\n return AllowListVerifierHelper.MAGICVALUE;\\n } else {\\n return bytes4(0);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf52c513257557b2bcfdf4210a1bc8fac05b6605dfdb8d8f30589bcc3a07b512a\"},\"contracts/interfaces/AllowListVerifier.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-or-later\\npragma solidity >=0.6.8;\\n\\nlibrary AllowListVerifierHelper {\\n /// @dev Value returned by a call to `isAllowed` if the check\\n /// was successful. The value is defined as:\\n /// bytes4(keccak256(\\\"isAllowed(address,uint256,bytes)\\\"))\\n bytes4 internal constant MAGICVALUE = 0x19a05a7e;\\n}\\n\\n///\\n/// @dev Standardized interface for an allowList manager for easyAuction\\n/// The interface was inspired by EIP-1271\\ninterface AllowListVerifier {\\n /// @dev Should return whether the a specific user has access to an auction\\n /// by returning the magic value from AllowListVerifierHelper\\n function isAllowed(\\n address user,\\n uint256 auctionId,\\n bytes calldata callData\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xbd0978c0fbf4e06e609615535face4d03bc156d890c916cea4dcb2d493ca1487\",\"license\":\"LGPL-3.0-or-later\"},\"contracts/libraries/IdToAddressBiMap.sol\":{\"content\":\"pragma solidity ^0.6.0;\\n\\n///////////////////////////////////////////////////////////////////////////////////////////////////////////\\n// Contract does not have test coverage, as it was nearly copied from:\\n// https://github.com/gnosis/solidity-data-structures/blob/master/contracts/libraries/IdToAddressBiMap.sol\\n// The only change is uint16 -> uint64\\n///////////////////////////////////////////////////////////////////////////////////////////////////////////\\n\\nlibrary IdToAddressBiMap {\\n struct Data {\\n mapping(uint64 => address) idToAddress;\\n mapping(address => uint64) addressToId;\\n }\\n\\n function hasId(Data storage self, uint64 id) internal view returns (bool) {\\n return self.idToAddress[id + 1] != address(0);\\n }\\n\\n function hasAddress(Data storage self, address addr)\\n internal\\n view\\n returns (bool)\\n {\\n return self.addressToId[addr] != 0;\\n }\\n\\n function getAddressAt(Data storage self, uint64 id)\\n internal\\n view\\n returns (address)\\n {\\n require(hasId(self, id), \\\"Must have ID to get Address\\\");\\n return self.idToAddress[id + 1];\\n }\\n\\n function getId(Data storage self, address addr)\\n internal\\n view\\n returns (uint64)\\n {\\n require(hasAddress(self, addr), \\\"Must have Address to get ID\\\");\\n return self.addressToId[addr] - 1;\\n }\\n\\n function insert(\\n Data storage self,\\n uint64 id,\\n address addr\\n ) internal returns (bool) {\\n require(addr != address(0), \\\"Cannot insert zero address\\\");\\n require(id != uint64(-1), \\\"Cannot insert max uint64\\\");\\n // Ensure bijectivity of the mappings\\n if (\\n self.addressToId[addr] != 0 ||\\n self.idToAddress[id + 1] != address(0)\\n ) {\\n return false;\\n }\\n self.idToAddress[id + 1] = addr;\\n self.addressToId[addr] = id + 1;\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x93efb312cc8c4956c462453559c8c0e1c090a0ac1f454d2ac9055fb7e4e3129d\"},\"contracts/libraries/IterableOrderedOrderSet.sol\":{\"content\":\"pragma solidity >=0.6.8;\\n\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\n\\nlibrary IterableOrderedOrderSet {\\n using SafeMath for uint96;\\n using IterableOrderedOrderSet for bytes32;\\n\\n // represents smallest possible value for an order under comparison of fn smallerThan()\\n bytes32 internal constant QUEUE_START =\\n 0x0000000000000000000000000000000000000000000000000000000000000001;\\n // represents highest possible value for an order under comparison of fn smallerThan()\\n bytes32 internal constant QUEUE_END =\\n 0xffffffffffffffffffffffffffffffffffffffff000000000000000000000001;\\n\\n /// The struct is used to implement a modified version of a doubly linked\\n /// list with sorted elements. The list starts from QUEUE_START to\\n /// QUEUE_END, and each node keeps track of its predecessor and successor.\\n /// Nodes can be added or removed.\\n ///\\n /// `next` and `prev` have a different role. The list is supposed to be\\n /// traversed with `next`. If `next` is empty, the node is not part of the\\n /// list. However, `prev` might be set for elements that are not in the\\n /// list, which is why it should not be used for traversing. Having a `prev`\\n /// set for elements not in the list is used to keep track of the history of\\n /// the position in the list of a removed element.\\n struct Data {\\n mapping(bytes32 => bytes32) nextMap;\\n mapping(bytes32 => bytes32) prevMap;\\n }\\n\\n struct Order {\\n uint64 owner;\\n uint96 buyAmount;\\n uint96 sellAmount;\\n }\\n\\n function initializeEmptyList(Data storage self) internal {\\n self.nextMap[QUEUE_START] = QUEUE_END;\\n self.prevMap[QUEUE_END] = QUEUE_START;\\n }\\n\\n function isEmpty(Data storage self) internal view returns (bool) {\\n return self.nextMap[QUEUE_START] == QUEUE_END;\\n }\\n\\n function insert(\\n Data storage self,\\n bytes32 elementToInsert,\\n bytes32 elementBeforeNewOne\\n ) internal returns (bool) {\\n (, , uint96 denominator) = decodeOrder(elementToInsert);\\n require(denominator != uint96(0), \\\"Inserting zero is not supported\\\");\\n require(\\n elementToInsert != QUEUE_START && elementToInsert != QUEUE_END,\\n \\\"Inserting element is not valid\\\"\\n );\\n if (contains(self, elementToInsert)) {\\n return false;\\n }\\n if (\\n elementBeforeNewOne != QUEUE_START &&\\n self.prevMap[elementBeforeNewOne] == bytes32(0)\\n ) {\\n return false;\\n }\\n if (!elementBeforeNewOne.smallerThan(elementToInsert)) {\\n return false;\\n }\\n\\n // `elementBeforeNewOne` might have been removed during the time it\\n // took to the transaction calling this function to be mined, so\\n // the new order cannot be appended directly to this. We follow the\\n // history of previous links backwards until we find an element in\\n // the list from which to start our search.\\n // Note that following the link backwards returns elements that are\\n // before `elementBeforeNewOne` in sorted order.\\n while (self.nextMap[elementBeforeNewOne] == bytes32(0)) {\\n elementBeforeNewOne = self.prevMap[elementBeforeNewOne];\\n }\\n\\n // `elementBeforeNewOne` belongs now to the linked list. We search the\\n // largest entry that is smaller than the element to insert.\\n bytes32 previous;\\n bytes32 current = elementBeforeNewOne;\\n do {\\n previous = current;\\n current = self.nextMap[current];\\n } while (current.smallerThan(elementToInsert));\\n // Note: previous < elementToInsert < current\\n self.nextMap[previous] = elementToInsert;\\n self.prevMap[current] = elementToInsert;\\n self.prevMap[elementToInsert] = previous;\\n self.nextMap[elementToInsert] = current;\\n\\n return true;\\n }\\n\\n /// The element is removed from the linked list, but the node retains\\n /// information on which predecessor it had, so that a node in the chain\\n /// can be reached by following the predecessor chain of deleted elements.\\n function removeKeepHistory(Data storage self, bytes32 elementToRemove)\\n internal\\n returns (bool)\\n {\\n if (!contains(self, elementToRemove)) {\\n return false;\\n }\\n bytes32 previousElement = self.prevMap[elementToRemove];\\n bytes32 nextElement = self.nextMap[elementToRemove];\\n self.nextMap[previousElement] = nextElement;\\n self.prevMap[nextElement] = previousElement;\\n self.nextMap[elementToRemove] = bytes32(0);\\n return true;\\n }\\n\\n /// Remove an element from the chain, clearing all related storage.\\n /// Note that no elements should be inserted using as a reference point a\\n /// node deleted after calling `remove`, since an element in the `prev`\\n /// chain might be missing.\\n function remove(Data storage self, bytes32 elementToRemove)\\n internal\\n returns (bool)\\n {\\n bool result = removeKeepHistory(self, elementToRemove);\\n if (result) {\\n self.prevMap[elementToRemove] = bytes32(0);\\n }\\n return result;\\n }\\n\\n function contains(Data storage self, bytes32 value)\\n internal\\n view\\n returns (bool)\\n {\\n if (value == QUEUE_START) {\\n return false;\\n }\\n // Note: QUEUE_END is not contained in the list since it has no\\n // successor.\\n return self.nextMap[value] != bytes32(0);\\n }\\n\\n // @dev orders are ordered by\\n // 1. their price - buyAmount/sellAmount\\n // 2. by the sellAmount\\n // 3. their userId,\\n function smallerThan(bytes32 orderLeft, bytes32 orderRight)\\n internal\\n pure\\n returns (bool)\\n {\\n (\\n uint64 userIdLeft,\\n uint96 priceNumeratorLeft,\\n uint96 priceDenominatorLeft\\n ) = decodeOrder(orderLeft);\\n (\\n uint64 userIdRight,\\n uint96 priceNumeratorRight,\\n uint96 priceDenominatorRight\\n ) = decodeOrder(orderRight);\\n\\n if (\\n priceNumeratorLeft.mul(priceDenominatorRight) <\\n priceNumeratorRight.mul(priceDenominatorLeft)\\n ) return true;\\n if (\\n priceNumeratorLeft.mul(priceDenominatorRight) >\\n priceNumeratorRight.mul(priceDenominatorLeft)\\n ) return false;\\n\\n if (priceNumeratorLeft < priceNumeratorRight) return true;\\n if (priceNumeratorLeft > priceNumeratorRight) return false;\\n require(\\n userIdLeft != userIdRight,\\n \\\"user is not allowed to place same order twice\\\"\\n );\\n if (userIdLeft < userIdRight) {\\n return true;\\n }\\n return false;\\n }\\n\\n function first(Data storage self) internal view returns (bytes32) {\\n require(!isEmpty(self), \\\"Trying to get first from empty set\\\");\\n return self.nextMap[QUEUE_START];\\n }\\n\\n function next(Data storage self, bytes32 value)\\n internal\\n view\\n returns (bytes32)\\n {\\n require(value != QUEUE_END, \\\"Trying to get next of last element\\\");\\n bytes32 nextElement = self.nextMap[value];\\n require(\\n nextElement != bytes32(0),\\n \\\"Trying to get next of non-existent element\\\"\\n );\\n return nextElement;\\n }\\n\\n function decodeOrder(bytes32 _orderData)\\n internal\\n pure\\n returns (\\n uint64 userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n )\\n {\\n // Note: converting to uint discards the binary digits that do not fit\\n // the type.\\n userId = uint64(uint256(_orderData) >> 192);\\n buyAmount = uint96(uint256(_orderData) >> 96);\\n sellAmount = uint96(uint256(_orderData));\\n }\\n\\n function encodeOrder(\\n uint64 userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n ) internal pure returns (bytes32) {\\n return\\n bytes32(\\n (uint256(userId) << 192) +\\n (uint256(buyAmount) << 96) +\\n uint256(sellAmount)\\n );\\n }\\n}\\n\",\"keccak256\":\"0xdcc090564f29439c38f4eb85115ba9ba4479a7494cd9e877fdc2b6d19b94d574\"},\"contracts/libraries/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Logic was copied and modified from here: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/SafeCast.sol\\n */\\nlibrary SafeCast {\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value < 2**96, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value < 2**64, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n}\\n\",\"keccak256\":\"0x9f12a3c511cd8ea260bc8faa7d2e4d59a823328ef07c26af506385aa3e92b200\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b5060004690507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f64aea53a8993ca7da1a35d4bd452fdb6171945e1d5fa9b7b34165966167f81c27f0984d5efd47d99151ae1be065a709e56c602102f24c1abc4008eb3f815a8d2178330604051602001808681526020018581526020018481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001955050505050506040516020818303038152906040528051906020012060808181525050506080516105e76100fa60003980610297528061058f52506105e76000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806319a05a7e146100465780631c841c421461011c578063f698da2514610212575b600080fd5b6100e76004803603606081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156100a357600080fd5b8201836020820111156100b557600080fd5b803590602001918460018302840111640100000000831117156100d757600080fd5b9091929391929390505050610230565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b6101dd6004803603608081101561013257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561019957600080fd5b8201836020820111156101ab57600080fd5b803590602001918460018302840111640100000000831117156101cd57600080fd5b9091929391929390505050610249565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b61021a61058d565b6040518082815260200191505060405180910390f35b600061023f8585338686610249565b9050949350505050565b6000806000808585606081101561025f57600080fd5b81019080803560ff169060200190929190803590602001909291908035906020019092919050505080935081945082955050505060007f00000000000000000000000000000000000000000000000000000000000000008a8a604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052805190602001209050600060018260405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012086868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156103ae573d6000803e3d6000fd5b50505060206040510351905060608973ffffffffffffffffffffffffffffffffffffffff1663f59c2f068c6040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561040d57600080fd5b505afa158015610421573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250602081101561044b57600080fd5b810190808051604051939291908464010000000082111561046b57600080fd5b8382019150602082018581111561048157600080fd5b825186600182028301116401000000008211171561049e57600080fd5b8083526020830192505050908051906020019080838360005b838110156104d25780820151818401526020810190506104b7565b50505050905090810190601f1680156104ff5780820380516001836020036101000a031916815260200191505b5060405250505090508173ffffffffffffffffffffffffffffffffffffffff1681806020019051602081101561053457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161415610576576319a05a7e60e01b9650505050505050610584565b600060e01b96505050505050505b95945050505050565b7f00000000000000000000000000000000000000000000000000000000000000008156fea26469706673582212205040dde2c25b6ed13c14d09e7203dc3b575acafeeb1674711e2b3ce7dc877a0364736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806319a05a7e146100465780631c841c421461011c578063f698da2514610212575b600080fd5b6100e76004803603606081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156100a357600080fd5b8201836020820111156100b557600080fd5b803590602001918460018302840111640100000000831117156100d757600080fd5b9091929391929390505050610230565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b6101dd6004803603608081101561013257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561019957600080fd5b8201836020820111156101ab57600080fd5b803590602001918460018302840111640100000000831117156101cd57600080fd5b9091929391929390505050610249565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b61021a61058d565b6040518082815260200191505060405180910390f35b600061023f8585338686610249565b9050949350505050565b6000806000808585606081101561025f57600080fd5b81019080803560ff169060200190929190803590602001909291908035906020019092919050505080935081945082955050505060007f00000000000000000000000000000000000000000000000000000000000000008a8a604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052805190602001209050600060018260405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012086868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156103ae573d6000803e3d6000fd5b50505060206040510351905060608973ffffffffffffffffffffffffffffffffffffffff1663f59c2f068c6040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561040d57600080fd5b505afa158015610421573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250602081101561044b57600080fd5b810190808051604051939291908464010000000082111561046b57600080fd5b8382019150602082018581111561048157600080fd5b825186600182028301116401000000008211171561049e57600080fd5b8083526020830192505050908051906020019080838360005b838110156104d25780820151818401526020810190506104b7565b50505050905090810190601f1680156104ff5780820380516001836020036101000a031916815260200191505b5060405250505090508173ffffffffffffffffffffffffffffffffffffffff1681806020019051602081101561053457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161415610576576319a05a7e60e01b9650505050505050610584565b600060e01b96505050505050505b95945050505050565b7f00000000000000000000000000000000000000000000000000000000000000008156fea26469706673582212205040dde2c25b6ed13c14d09e7203dc3b575acafeeb1674711e2b3ce7dc877a0364736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "stateVariables": { + "DOMAIN_NAME": { + "details": "The EIP-712 domain name used for computing the domain separator." + }, + "DOMAIN_TYPE_HASH": { + "details": "The EIP-712 domain type hash used for computing the domain separator." + }, + "DOMAIN_VERSION": { + "details": "The EIP-712 domain version used for computing the domain separator." + }, + "domainSeparator": { + "details": "The domain separator used for signing orders that gets mixed in making signatures for different domains incompatible. This domain separator is computed following the EIP-712 standard and has replay protection mixed in so that signed orders are only valid for specific GPv2 contracts." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/binancesmartchaintestnet/DepositAndPlaceOrder.json b/deployments/binancesmartchaintestnet/DepositAndPlaceOrder.json new file mode 100644 index 0000000..0aa0ccf --- /dev/null +++ b/deployments/binancesmartchaintestnet/DepositAndPlaceOrder.json @@ -0,0 +1,135 @@ +{ + "address": "0x14082EDeFCa073578d2C16E8fB42967bEc188E59", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "easyAuctionAddress", + "type": "address" + }, + { + "internalType": "address", + "name": "_nativeTokenWrapper", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "internalType": "uint96[]", + "name": "_minBuyAmounts", + "type": "uint96[]" + }, + { + "internalType": "bytes32[]", + "name": "_prevSellOrders", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "allowListCallData", + "type": "bytes" + } + ], + "name": "depositAndPlaceOrder", + "outputs": [ + { + "internalType": "uint64", + "name": "userId", + "type": "uint64" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "easyAuction", + "outputs": [ + { + "internalType": "contract EasyAuction", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nativeTokenWrapper", + "outputs": [ + { + "internalType": "contract IWETH", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xd5d0460fabfb56ac66056b6ba228199b0f28c46a060866c7ad2d124411094ad4", + "receipt": { + "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", + "from": "0x1F90D0754A6822A5d9622600A1b52893d93Bb646", + "contractAddress": null, + "transactionIndex": 17, + "gasUsed": "439829", + "logsBloom": "0x00000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000200000000000000000000000000000020000000000000000010000000000004020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000200000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0xa3c683281bef487d68ac7740d15b6aa9f1f23ccfbb50cf62aea1fae469a5daaf", + "transactionHash": "0xd5d0460fabfb56ac66056b6ba228199b0f28c46a060866c7ad2d124411094ad4", + "logs": [ + { + "transactionIndex": 17, + "blockNumber": 29692306, + "transactionHash": "0xd5d0460fabfb56ac66056b6ba228199b0f28c46a060866c7ad2d124411094ad4", + "address": "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd", + "topics": [ + "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", + "0x00000000000000000000000014082edefca073578d2c16e8fb42967bec188e59", + "0x000000000000000000000000231f3fd7c3e3c9a2c8a03b72132c31241df0a26c" + ], + "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "logIndex": 4, + "blockHash": "0xa3c683281bef487d68ac7740d15b6aa9f1f23ccfbb50cf62aea1fae469a5daaf" + } + ], + "blockNumber": 29692306, + "cumulativeGasUsed": "1771233", + "status": 1, + "byzantium": true + }, + "args": [ + "0x231F3Fd7c3E3C9a2c8A03B72132c31241DF0a26C", + "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd" + ], + "numDeployments": 1, + "solcInputHash": "a81c49f8848cbbe2b3d955ebaff2de99", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"easyAuctionAddress\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_nativeTokenWrapper\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"internalType\":\"uint96[]\",\"name\":\"_minBuyAmounts\",\"type\":\"uint96[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_prevSellOrders\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"allowListCallData\",\"type\":\"bytes\"}],\"name\":\"depositAndPlaceOrder\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"userId\",\"type\":\"uint64\"}],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"easyAuction\",\"outputs\":[{\"internalType\":\"contract EasyAuction\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nativeTokenWrapper\",\"outputs\":[{\"internalType\":\"contract IWETH\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/wrappers/DepositAndPlaceOrder.sol\":\"DepositAndPlaceOrder\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(_owner == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0xf7c39c7e6d06ed3bda90cfefbcbf2ddc32c599c3d6721746546ad64946efccaa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute\\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\\n }\\n}\\n\",\"keccak256\":\"0x363bd3b45201f07c9b71c2edc96533468cf14a3d029fabd82fddceb1eb3ebd9c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x3b21f2c8d626de3b9925ae33e972d8bf5c8b1bffb3f4ee94daeed7d0679036e6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x5f02220344881ce43204ae4a6281145a67bc52c2bb1290a791857df3d19d78f5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf12dfbe97e6276980b83d2830bb0eb75e0cf4f3e626c2471137f82158ae6a0fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa6a15ddddcbf29d2922a1e0d4151b5d2d33da24b93cc9ebc12390e0d855532f8\",\"license\":\"MIT\"},\"contracts/EasyAuction.sol\":{\"content\":\"pragma solidity >=0.6.8;\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"./libraries/IterableOrderedOrderSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"./libraries/IdToAddressBiMap.sol\\\";\\nimport \\\"./libraries/SafeCast.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"./interfaces/AllowListVerifier.sol\\\";\\n\\ncontract EasyAuction is Ownable {\\n using SafeERC20 for IERC20;\\n using SafeMath for uint64;\\n using SafeMath for uint96;\\n using SafeMath for uint256;\\n using SafeCast for uint256;\\n using IterableOrderedOrderSet for IterableOrderedOrderSet.Data;\\n using IterableOrderedOrderSet for bytes32;\\n using IdToAddressBiMap for IdToAddressBiMap.Data;\\n\\n modifier atStageOrderPlacement(uint256 auctionId) {\\n require(\\n block.timestamp < auctionData[auctionId].auctionEndDate,\\n \\\"no longer in order placement phase\\\"\\n );\\n _;\\n }\\n\\n modifier atStageOrderPlacementAndCancelation(uint256 auctionId) {\\n require(\\n block.timestamp < auctionData[auctionId].orderCancellationEndDate,\\n \\\"no longer in order placement and cancelation phase\\\"\\n );\\n _;\\n }\\n\\n modifier atStageSolutionSubmission(uint256 auctionId) {\\n {\\n uint256 auctionEndDate = auctionData[auctionId].auctionEndDate;\\n require(\\n auctionEndDate != 0 &&\\n block.timestamp >= auctionEndDate &&\\n auctionData[auctionId].clearingPriceOrder == bytes32(0),\\n \\\"Auction not in solution submission phase\\\"\\n );\\n }\\n _;\\n }\\n\\n modifier atStageFinished(uint256 auctionId) {\\n require(\\n auctionData[auctionId].clearingPriceOrder != bytes32(0),\\n \\\"Auction not yet finished\\\"\\n );\\n _;\\n }\\n\\n event NewSellOrder(\\n uint256 indexed auctionId,\\n uint64 indexed userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n );\\n event CancellationSellOrder(\\n uint256 indexed auctionId,\\n uint64 indexed userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n );\\n event ClaimedFromOrder(\\n uint256 indexed auctionId,\\n uint64 indexed userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n );\\n event NewUser(uint64 indexed userId, address indexed userAddress);\\n event NewAuction(\\n uint256 indexed auctionId,\\n IERC20 indexed _auctioningToken,\\n IERC20 indexed _biddingToken,\\n uint256 orderCancellationEndDate,\\n uint256 auctionEndDate,\\n uint64 userId,\\n uint96 _auctionedSellAmount,\\n uint96 _minBuyAmount,\\n uint256 minimumBiddingAmountPerOrder,\\n uint256 minFundingThreshold,\\n address allowListContract,\\n bytes allowListData\\n );\\n event AuctionCleared(\\n uint256 indexed auctionId,\\n uint96 soldAuctioningTokens,\\n uint96 soldBiddingTokens,\\n bytes32 clearingPriceOrder\\n );\\n event UserRegistration(address indexed user, uint64 userId);\\n\\n struct AuctionData {\\n IERC20 auctioningToken;\\n IERC20 biddingToken;\\n uint256 orderCancellationEndDate;\\n uint256 auctionEndDate;\\n bytes32 initialAuctionOrder;\\n uint256 minimumBiddingAmountPerOrder;\\n uint256 interimSumBidAmount;\\n bytes32 interimOrder;\\n bytes32 clearingPriceOrder;\\n uint96 volumeClearingPriceOrder;\\n bool minFundingThresholdNotReached;\\n bool isAtomicClosureAllowed;\\n uint256 feeNumerator;\\n uint256 minFundingThreshold;\\n }\\n mapping(uint256 => IterableOrderedOrderSet.Data) internal sellOrders;\\n mapping(uint256 => AuctionData) public auctionData;\\n mapping(uint256 => address) public auctionAccessManager;\\n mapping(uint256 => bytes) public auctionAccessData;\\n\\n IdToAddressBiMap.Data private registeredUsers;\\n uint64 public numUsers;\\n uint256 public auctionCounter;\\n\\n constructor() public Ownable() {}\\n\\n uint256 public feeNumerator = 0;\\n uint256 public constant FEE_DENOMINATOR = 1000;\\n uint64 public feeReceiverUserId = 1;\\n\\n function setFeeParameters(\\n uint256 newFeeNumerator,\\n address newfeeReceiverAddress\\n ) public onlyOwner() {\\n require(\\n newFeeNumerator <= 15,\\n \\\"Fee is not allowed to be set higher than 1.5%\\\"\\n );\\n // caution: for currently running auctions, the feeReceiverUserId is changing as well.\\n feeReceiverUserId = getUserId(newfeeReceiverAddress);\\n feeNumerator = newFeeNumerator;\\n }\\n\\n // @dev: function to intiate a new auction\\n // Warning: In case the auction is expected to raise more than\\n // 2^96 units of the biddingToken, don't start the auction, as\\n // it will not be settlable. This corresponds to about 79\\n // billion DAI.\\n //\\n // Prices between biddingToken and auctioningToken are expressed by a\\n // fraction whose components are stored as uint96.\\n function initiateAuction(\\n IERC20 _auctioningToken,\\n IERC20 _biddingToken,\\n uint256 orderCancellationEndDate,\\n uint256 auctionEndDate,\\n uint96 _auctionedSellAmount,\\n uint96 _minBuyAmount,\\n uint256 minimumBiddingAmountPerOrder,\\n uint256 minFundingThreshold,\\n bool isAtomicClosureAllowed,\\n address accessManagerContract,\\n bytes memory accessManagerContractData\\n ) public returns (uint256) {\\n // withdraws sellAmount + fees\\n _auctioningToken.safeTransferFrom(\\n msg.sender,\\n address(this),\\n _auctionedSellAmount.mul(FEE_DENOMINATOR.add(feeNumerator)).div(\\n FEE_DENOMINATOR\\n ) //[0]\\n );\\n require(_auctionedSellAmount > 0, \\\"cannot auction zero tokens\\\");\\n require(_minBuyAmount > 0, \\\"tokens cannot be auctioned for free\\\");\\n require(\\n minimumBiddingAmountPerOrder > 0,\\n \\\"minimumBiddingAmountPerOrder is not allowed to be zero\\\"\\n );\\n require(\\n orderCancellationEndDate <= auctionEndDate,\\n \\\"time periods are not configured correctly\\\"\\n );\\n require(\\n auctionEndDate > block.timestamp,\\n \\\"auction end date must be in the future\\\"\\n );\\n auctionCounter = auctionCounter.add(1);\\n sellOrders[auctionCounter].initializeEmptyList();\\n uint64 userId = getUserId(msg.sender);\\n auctionData[auctionCounter] = AuctionData(\\n _auctioningToken,\\n _biddingToken,\\n orderCancellationEndDate,\\n auctionEndDate,\\n IterableOrderedOrderSet.encodeOrder(\\n userId,\\n _minBuyAmount,\\n _auctionedSellAmount\\n ),\\n minimumBiddingAmountPerOrder,\\n 0,\\n IterableOrderedOrderSet.QUEUE_START,\\n bytes32(0),\\n 0,\\n false,\\n isAtomicClosureAllowed,\\n feeNumerator,\\n minFundingThreshold\\n );\\n auctionAccessManager[auctionCounter] = accessManagerContract;\\n auctionAccessData[auctionCounter] = accessManagerContractData;\\n emit NewAuction(\\n auctionCounter,\\n _auctioningToken,\\n _biddingToken,\\n orderCancellationEndDate,\\n auctionEndDate,\\n userId,\\n _auctionedSellAmount,\\n _minBuyAmount,\\n minimumBiddingAmountPerOrder,\\n minFundingThreshold,\\n accessManagerContract,\\n accessManagerContractData\\n );\\n return auctionCounter;\\n }\\n\\n function placeSellOrders(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmounts,\\n uint96[] memory _sellAmounts,\\n bytes32[] memory _prevSellOrders,\\n bytes calldata allowListCallData\\n ) external atStageOrderPlacement(auctionId) returns (uint64 userId) {\\n return\\n _placeSellOrders(\\n auctionId,\\n _minBuyAmounts,\\n _sellAmounts,\\n _prevSellOrders,\\n allowListCallData,\\n msg.sender\\n );\\n }\\n\\n function placeSellOrdersOnBehalf(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmounts,\\n uint96[] memory _sellAmounts,\\n bytes32[] memory _prevSellOrders,\\n bytes calldata allowListCallData,\\n address orderSubmitter\\n ) external atStageOrderPlacement(auctionId) returns (uint64 userId) {\\n return\\n _placeSellOrders(\\n auctionId,\\n _minBuyAmounts,\\n _sellAmounts,\\n _prevSellOrders,\\n allowListCallData,\\n orderSubmitter\\n );\\n }\\n\\n function _placeSellOrders(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmounts,\\n uint96[] memory _sellAmounts,\\n bytes32[] memory _prevSellOrders,\\n bytes calldata allowListCallData,\\n address orderSubmitter\\n ) internal returns (uint64 userId) {\\n {\\n address allowListManager = auctionAccessManager[auctionId];\\n if (allowListManager != address(0)) {\\n require(\\n AllowListVerifier(allowListManager).isAllowed(\\n orderSubmitter,\\n auctionId,\\n allowListCallData\\n ) == AllowListVerifierHelper.MAGICVALUE,\\n \\\"user not allowed to place order\\\"\\n );\\n }\\n }\\n {\\n (\\n ,\\n uint96 buyAmountOfInitialAuctionOrder,\\n uint96 sellAmountOfInitialAuctionOrder\\n ) = auctionData[auctionId].initialAuctionOrder.decodeOrder();\\n for (uint256 i = 0; i < _minBuyAmounts.length; i++) {\\n require(\\n _minBuyAmounts[i].mul(buyAmountOfInitialAuctionOrder) <\\n sellAmountOfInitialAuctionOrder.mul(_sellAmounts[i]),\\n \\\"limit price not better than mimimal offer\\\"\\n );\\n }\\n }\\n uint256 sumOfSellAmounts = 0;\\n userId = getUserId(orderSubmitter);\\n uint256 minimumBiddingAmountPerOrder =\\n auctionData[auctionId].minimumBiddingAmountPerOrder;\\n for (uint256 i = 0; i < _minBuyAmounts.length; i++) {\\n require(\\n _minBuyAmounts[i] > 0,\\n \\\"_minBuyAmounts must be greater than 0\\\"\\n );\\n // orders should have a minimum bid size in order to limit the gas\\n // required to compute the final price of the auction.\\n require(\\n _sellAmounts[i] > minimumBiddingAmountPerOrder,\\n \\\"order too small\\\"\\n );\\n if (\\n sellOrders[auctionId].insert(\\n IterableOrderedOrderSet.encodeOrder(\\n userId,\\n _minBuyAmounts[i],\\n _sellAmounts[i]\\n ),\\n _prevSellOrders[i]\\n )\\n ) {\\n sumOfSellAmounts = sumOfSellAmounts.add(_sellAmounts[i]);\\n emit NewSellOrder(\\n auctionId,\\n userId,\\n _minBuyAmounts[i],\\n _sellAmounts[i]\\n );\\n }\\n }\\n auctionData[auctionId].biddingToken.safeTransferFrom(\\n msg.sender,\\n address(this),\\n sumOfSellAmounts\\n ); //[1]\\n }\\n\\n function cancelSellOrders(uint256 auctionId, bytes32[] memory _sellOrders)\\n public\\n atStageOrderPlacementAndCancelation(auctionId)\\n {\\n uint64 userId = getUserId(msg.sender);\\n uint256 claimableAmount = 0;\\n for (uint256 i = 0; i < _sellOrders.length; i++) {\\n // Note: we keep the back pointer of the deleted element so that\\n // it can be used as a reference point to insert a new node.\\n bool success =\\n sellOrders[auctionId].removeKeepHistory(_sellOrders[i]);\\n if (success) {\\n (\\n uint64 userIdOfIter,\\n uint96 buyAmountOfIter,\\n uint96 sellAmountOfIter\\n ) = _sellOrders[i].decodeOrder();\\n require(\\n userIdOfIter == userId,\\n \\\"Only the user can cancel his orders\\\"\\n );\\n claimableAmount = claimableAmount.add(sellAmountOfIter);\\n emit CancellationSellOrder(\\n auctionId,\\n userId,\\n buyAmountOfIter,\\n sellAmountOfIter\\n );\\n }\\n }\\n auctionData[auctionId].biddingToken.safeTransfer(\\n msg.sender,\\n claimableAmount\\n ); //[2]\\n }\\n\\n function precalculateSellAmountSum(\\n uint256 auctionId,\\n uint256 iterationSteps\\n ) public atStageSolutionSubmission(auctionId) {\\n (, , uint96 auctioneerSellAmount) =\\n auctionData[auctionId].initialAuctionOrder.decodeOrder();\\n uint256 sumBidAmount = auctionData[auctionId].interimSumBidAmount;\\n bytes32 iterOrder = auctionData[auctionId].interimOrder;\\n\\n for (uint256 i = 0; i < iterationSteps; i++) {\\n iterOrder = sellOrders[auctionId].next(iterOrder);\\n (, , uint96 sellAmountOfIter) = iterOrder.decodeOrder();\\n sumBidAmount = sumBidAmount.add(sellAmountOfIter);\\n }\\n\\n require(\\n iterOrder != IterableOrderedOrderSet.QUEUE_END,\\n \\\"reached end of order list\\\"\\n );\\n\\n // it is checked that not too many iteration steps were taken:\\n // require that the sum of SellAmounts times the price of the last order\\n // is not more than initially sold amount\\n (, uint96 buyAmountOfIter, uint96 sellAmountOfIter) =\\n iterOrder.decodeOrder();\\n require(\\n sumBidAmount.mul(buyAmountOfIter) <\\n auctioneerSellAmount.mul(sellAmountOfIter),\\n \\\"too many orders summed up\\\"\\n );\\n\\n auctionData[auctionId].interimSumBidAmount = sumBidAmount;\\n auctionData[auctionId].interimOrder = iterOrder;\\n }\\n\\n function settleAuctionAtomically(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmount,\\n uint96[] memory _sellAmount,\\n bytes32[] memory _prevSellOrder,\\n bytes calldata allowListCallData\\n ) public atStageSolutionSubmission(auctionId) {\\n require(\\n auctionData[auctionId].isAtomicClosureAllowed,\\n \\\"not allowed to settle auction atomically\\\"\\n );\\n require(\\n _minBuyAmount.length == 1 && _sellAmount.length == 1,\\n \\\"Only one order can be placed atomically\\\"\\n );\\n uint64 userId = getUserId(msg.sender);\\n require(\\n auctionData[auctionId].interimOrder.smallerThan(\\n IterableOrderedOrderSet.encodeOrder(\\n userId,\\n _minBuyAmount[0],\\n _sellAmount[0]\\n )\\n ),\\n \\\"precalculateSellAmountSum is already too advanced\\\"\\n );\\n _placeSellOrders(\\n auctionId,\\n _minBuyAmount,\\n _sellAmount,\\n _prevSellOrder,\\n allowListCallData,\\n msg.sender\\n );\\n settleAuction(auctionId);\\n }\\n\\n // @dev function settling the auction and calculating the price\\n function settleAuction(uint256 auctionId)\\n public\\n atStageSolutionSubmission(auctionId)\\n returns (bytes32 clearingOrder)\\n {\\n (\\n uint64 auctioneerId,\\n uint96 minAuctionedBuyAmount,\\n uint96 fullAuctionedAmount\\n ) = auctionData[auctionId].initialAuctionOrder.decodeOrder();\\n\\n uint256 currentBidSum = auctionData[auctionId].interimSumBidAmount;\\n bytes32 currentOrder = auctionData[auctionId].interimOrder;\\n uint256 buyAmountOfIter;\\n uint256 sellAmountOfIter;\\n uint96 fillVolumeOfAuctioneerOrder = fullAuctionedAmount;\\n // Sum order up, until fullAuctionedAmount is fully bought or queue end is reached\\n do {\\n bytes32 nextOrder = sellOrders[auctionId].next(currentOrder);\\n if (nextOrder == IterableOrderedOrderSet.QUEUE_END) {\\n break;\\n }\\n currentOrder = nextOrder;\\n (, buyAmountOfIter, sellAmountOfIter) = currentOrder.decodeOrder();\\n currentBidSum = currentBidSum.add(sellAmountOfIter);\\n } while (\\n currentBidSum.mul(buyAmountOfIter) <\\n fullAuctionedAmount.mul(sellAmountOfIter)\\n );\\n\\n if (\\n currentBidSum > 0 &&\\n currentBidSum.mul(buyAmountOfIter) >=\\n fullAuctionedAmount.mul(sellAmountOfIter)\\n ) {\\n // All considered/summed orders are sufficient to close the auction fully\\n // at price between current and previous orders.\\n uint256 uncoveredBids =\\n currentBidSum.sub(\\n fullAuctionedAmount.mul(sellAmountOfIter).div(\\n buyAmountOfIter\\n )\\n );\\n\\n if (sellAmountOfIter >= uncoveredBids) {\\n //[13]\\n // Auction fully filled via partial match of currentOrder\\n uint256 sellAmountClearingOrder =\\n sellAmountOfIter.sub(uncoveredBids);\\n auctionData[auctionId]\\n .volumeClearingPriceOrder = sellAmountClearingOrder\\n .toUint96();\\n currentBidSum = currentBidSum.sub(uncoveredBids);\\n clearingOrder = currentOrder;\\n } else {\\n //[14]\\n // Auction fully filled via price strictly between currentOrder and the order\\n // immediately before. For a proof, see the security-considerations.md\\n currentBidSum = currentBidSum.sub(sellAmountOfIter);\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\n 0,\\n fullAuctionedAmount,\\n currentBidSum.toUint96()\\n );\\n }\\n } else {\\n // All considered/summed orders are not sufficient to close the auction fully at price of last order //[18]\\n // Either a higher price must be used or auction is only partially filled\\n\\n if (currentBidSum > minAuctionedBuyAmount) {\\n //[15]\\n // Price higher than last order would fill the auction\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\n 0,\\n fullAuctionedAmount,\\n currentBidSum.toUint96()\\n );\\n } else {\\n //[16]\\n // Even at the initial auction price, the auction is partially filled\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\n 0,\\n fullAuctionedAmount,\\n minAuctionedBuyAmount\\n );\\n fillVolumeOfAuctioneerOrder = currentBidSum\\n .mul(fullAuctionedAmount)\\n .div(minAuctionedBuyAmount)\\n .toUint96();\\n }\\n }\\n auctionData[auctionId].clearingPriceOrder = clearingOrder;\\n\\n if (auctionData[auctionId].minFundingThreshold > currentBidSum) {\\n auctionData[auctionId].minFundingThresholdNotReached = true;\\n }\\n processFeesAndAuctioneerFunds(\\n auctionId,\\n fillVolumeOfAuctioneerOrder,\\n auctioneerId,\\n fullAuctionedAmount\\n );\\n emit AuctionCleared(\\n auctionId,\\n fillVolumeOfAuctioneerOrder,\\n uint96(currentBidSum),\\n clearingOrder\\n );\\n // Gas refunds\\n auctionAccessManager[auctionId] = address(0);\\n delete auctionAccessData[auctionId];\\n auctionData[auctionId].initialAuctionOrder = bytes32(0);\\n auctionData[auctionId].interimOrder = bytes32(0);\\n auctionData[auctionId].interimSumBidAmount = uint256(0);\\n auctionData[auctionId].minimumBiddingAmountPerOrder = uint256(0);\\n }\\n\\n function claimFromParticipantOrder(\\n uint256 auctionId,\\n bytes32[] memory orders\\n )\\n public\\n atStageFinished(auctionId)\\n returns (\\n uint256 sumAuctioningTokenAmount,\\n uint256 sumBiddingTokenAmount\\n )\\n {\\n for (uint256 i = 0; i < orders.length; i++) {\\n // Note: we don't need to keep any information about the node since\\n // no new elements need to be inserted.\\n require(\\n sellOrders[auctionId].remove(orders[i]),\\n \\\"order is no longer claimable\\\"\\n );\\n }\\n AuctionData memory auction = auctionData[auctionId];\\n (, uint96 priceNumerator, uint96 priceDenominator) =\\n auction.clearingPriceOrder.decodeOrder();\\n (uint64 userId, , ) = orders[0].decodeOrder();\\n bool minFundingThresholdNotReached =\\n auctionData[auctionId].minFundingThresholdNotReached;\\n for (uint256 i = 0; i < orders.length; i++) {\\n (uint64 userIdOrder, uint96 buyAmount, uint96 sellAmount) =\\n orders[i].decodeOrder();\\n require(\\n userIdOrder == userId,\\n \\\"only allowed to claim for same user\\\"\\n );\\n if (minFundingThresholdNotReached) {\\n //[10]\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(sellAmount);\\n } else {\\n //[23]\\n if (orders[i] == auction.clearingPriceOrder) {\\n //[25]\\n sumAuctioningTokenAmount = sumAuctioningTokenAmount.add(\\n auction\\n .volumeClearingPriceOrder\\n .mul(priceNumerator)\\n .div(priceDenominator)\\n );\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(\\n sellAmount.sub(auction.volumeClearingPriceOrder)\\n );\\n } else {\\n if (orders[i].smallerThan(auction.clearingPriceOrder)) {\\n //[17]\\n sumAuctioningTokenAmount = sumAuctioningTokenAmount.add(\\n sellAmount.mul(priceNumerator).div(priceDenominator)\\n );\\n } else {\\n //[24]\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(\\n sellAmount\\n );\\n }\\n }\\n }\\n emit ClaimedFromOrder(auctionId, userId, buyAmount, sellAmount);\\n }\\n sendOutTokens(\\n auctionId,\\n sumAuctioningTokenAmount,\\n sumBiddingTokenAmount,\\n userId\\n ); //[3]\\n }\\n\\n function processFeesAndAuctioneerFunds(\\n uint256 auctionId,\\n uint256 fillVolumeOfAuctioneerOrder,\\n uint64 auctioneerId,\\n uint96 fullAuctionedAmount\\n ) internal {\\n uint256 feeAmount =\\n fullAuctionedAmount.mul(auctionData[auctionId].feeNumerator).div(\\n FEE_DENOMINATOR\\n ); //[20]\\n if (auctionData[auctionId].minFundingThresholdNotReached) {\\n sendOutTokens(\\n auctionId,\\n fullAuctionedAmount.add(feeAmount),\\n 0,\\n auctioneerId\\n ); //[4]\\n } else {\\n //[11]\\n (, uint96 priceNumerator, uint96 priceDenominator) =\\n auctionData[auctionId].clearingPriceOrder.decodeOrder();\\n uint256 unsettledAuctionTokens =\\n fullAuctionedAmount.sub(fillVolumeOfAuctioneerOrder);\\n uint256 auctioningTokenAmount =\\n unsettledAuctionTokens.add(\\n feeAmount.mul(unsettledAuctionTokens).div(\\n fullAuctionedAmount\\n )\\n );\\n uint256 biddingTokenAmount =\\n fillVolumeOfAuctioneerOrder.mul(priceDenominator).div(\\n priceNumerator\\n );\\n sendOutTokens(\\n auctionId,\\n auctioningTokenAmount,\\n biddingTokenAmount,\\n auctioneerId\\n ); //[5]\\n sendOutTokens(\\n auctionId,\\n feeAmount.mul(fillVolumeOfAuctioneerOrder).div(\\n fullAuctionedAmount\\n ),\\n 0,\\n feeReceiverUserId\\n ); //[7]\\n }\\n }\\n\\n function sendOutTokens(\\n uint256 auctionId,\\n uint256 auctioningTokenAmount,\\n uint256 biddingTokenAmount,\\n uint64 userId\\n ) internal {\\n address userAddress = registeredUsers.getAddressAt(userId);\\n if (auctioningTokenAmount > 0) {\\n auctionData[auctionId].auctioningToken.safeTransfer(\\n userAddress,\\n auctioningTokenAmount\\n );\\n }\\n if (biddingTokenAmount > 0) {\\n auctionData[auctionId].biddingToken.safeTransfer(\\n userAddress,\\n biddingTokenAmount\\n );\\n }\\n }\\n\\n function registerUser(address user) public returns (uint64 userId) {\\n numUsers = numUsers.add(1).toUint64();\\n require(\\n registeredUsers.insert(numUsers, user),\\n \\\"User already registered\\\"\\n );\\n userId = numUsers;\\n emit UserRegistration(user, userId);\\n }\\n\\n function getUserId(address user) public returns (uint64 userId) {\\n if (registeredUsers.hasAddress(user)) {\\n userId = registeredUsers.getId(user);\\n } else {\\n userId = registerUser(user);\\n emit NewUser(userId, user);\\n }\\n }\\n\\n function getSecondsRemainingInBatch(uint256 auctionId)\\n public\\n view\\n returns (uint256)\\n {\\n if (auctionData[auctionId].auctionEndDate < block.timestamp) {\\n return 0;\\n }\\n return auctionData[auctionId].auctionEndDate.sub(block.timestamp);\\n }\\n\\n function containsOrder(uint256 auctionId, bytes32 order)\\n public\\n view\\n returns (bool)\\n {\\n return sellOrders[auctionId].contains(order);\\n }\\n}\\n\",\"keccak256\":\"0x4fbbc969d2b2de6d6b9dbb99e16cbf7cdb2dfc0f2b20cac4cbb129a700ab9b69\"},\"contracts/interfaces/AllowListVerifier.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-or-later\\npragma solidity >=0.6.8;\\n\\nlibrary AllowListVerifierHelper {\\n /// @dev Value returned by a call to `isAllowed` if the check\\n /// was successful. The value is defined as:\\n /// bytes4(keccak256(\\\"isAllowed(address,uint256,bytes)\\\"))\\n bytes4 internal constant MAGICVALUE = 0x19a05a7e;\\n}\\n\\n///\\n/// @dev Standardized interface for an allowList manager for easyAuction\\n/// The interface was inspired by EIP-1271\\ninterface AllowListVerifier {\\n /// @dev Should return whether the a specific user has access to an auction\\n /// by returning the magic value from AllowListVerifierHelper\\n function isAllowed(\\n address user,\\n uint256 auctionId,\\n bytes calldata callData\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xbd0978c0fbf4e06e609615535face4d03bc156d890c916cea4dcb2d493ca1487\",\"license\":\"LGPL-3.0-or-later\"},\"contracts/interfaces/IWETH.sol\":{\"content\":\"pragma solidity >=0.6.0;\\n\\ninterface IWETH {\\n function deposit() external payable;\\n\\n function transfer(address to, uint256 value) external returns (bool);\\n\\n function withdraw(uint256) external;\\n}\\n\",\"keccak256\":\"0x9b7c053398e2431119efeffc0c61e201dbc2db894f414762d5b22b04137589d4\"},\"contracts/libraries/IdToAddressBiMap.sol\":{\"content\":\"pragma solidity ^0.6.0;\\n\\n///////////////////////////////////////////////////////////////////////////////////////////////////////////\\n// Contract does not have test coverage, as it was nearly copied from:\\n// https://github.com/gnosis/solidity-data-structures/blob/master/contracts/libraries/IdToAddressBiMap.sol\\n// The only change is uint16 -> uint64\\n///////////////////////////////////////////////////////////////////////////////////////////////////////////\\n\\nlibrary IdToAddressBiMap {\\n struct Data {\\n mapping(uint64 => address) idToAddress;\\n mapping(address => uint64) addressToId;\\n }\\n\\n function hasId(Data storage self, uint64 id) internal view returns (bool) {\\n return self.idToAddress[id + 1] != address(0);\\n }\\n\\n function hasAddress(Data storage self, address addr)\\n internal\\n view\\n returns (bool)\\n {\\n return self.addressToId[addr] != 0;\\n }\\n\\n function getAddressAt(Data storage self, uint64 id)\\n internal\\n view\\n returns (address)\\n {\\n require(hasId(self, id), \\\"Must have ID to get Address\\\");\\n return self.idToAddress[id + 1];\\n }\\n\\n function getId(Data storage self, address addr)\\n internal\\n view\\n returns (uint64)\\n {\\n require(hasAddress(self, addr), \\\"Must have Address to get ID\\\");\\n return self.addressToId[addr] - 1;\\n }\\n\\n function insert(\\n Data storage self,\\n uint64 id,\\n address addr\\n ) internal returns (bool) {\\n require(addr != address(0), \\\"Cannot insert zero address\\\");\\n require(id != uint64(-1), \\\"Cannot insert max uint64\\\");\\n // Ensure bijectivity of the mappings\\n if (\\n self.addressToId[addr] != 0 ||\\n self.idToAddress[id + 1] != address(0)\\n ) {\\n return false;\\n }\\n self.idToAddress[id + 1] = addr;\\n self.addressToId[addr] = id + 1;\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x93efb312cc8c4956c462453559c8c0e1c090a0ac1f454d2ac9055fb7e4e3129d\"},\"contracts/libraries/IterableOrderedOrderSet.sol\":{\"content\":\"pragma solidity >=0.6.8;\\n\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\n\\nlibrary IterableOrderedOrderSet {\\n using SafeMath for uint96;\\n using IterableOrderedOrderSet for bytes32;\\n\\n // represents smallest possible value for an order under comparison of fn smallerThan()\\n bytes32 internal constant QUEUE_START =\\n 0x0000000000000000000000000000000000000000000000000000000000000001;\\n // represents highest possible value for an order under comparison of fn smallerThan()\\n bytes32 internal constant QUEUE_END =\\n 0xffffffffffffffffffffffffffffffffffffffff000000000000000000000001;\\n\\n /// The struct is used to implement a modified version of a doubly linked\\n /// list with sorted elements. The list starts from QUEUE_START to\\n /// QUEUE_END, and each node keeps track of its predecessor and successor.\\n /// Nodes can be added or removed.\\n ///\\n /// `next` and `prev` have a different role. The list is supposed to be\\n /// traversed with `next`. If `next` is empty, the node is not part of the\\n /// list. However, `prev` might be set for elements that are not in the\\n /// list, which is why it should not be used for traversing. Having a `prev`\\n /// set for elements not in the list is used to keep track of the history of\\n /// the position in the list of a removed element.\\n struct Data {\\n mapping(bytes32 => bytes32) nextMap;\\n mapping(bytes32 => bytes32) prevMap;\\n }\\n\\n struct Order {\\n uint64 owner;\\n uint96 buyAmount;\\n uint96 sellAmount;\\n }\\n\\n function initializeEmptyList(Data storage self) internal {\\n self.nextMap[QUEUE_START] = QUEUE_END;\\n self.prevMap[QUEUE_END] = QUEUE_START;\\n }\\n\\n function isEmpty(Data storage self) internal view returns (bool) {\\n return self.nextMap[QUEUE_START] == QUEUE_END;\\n }\\n\\n function insert(\\n Data storage self,\\n bytes32 elementToInsert,\\n bytes32 elementBeforeNewOne\\n ) internal returns (bool) {\\n (, , uint96 denominator) = decodeOrder(elementToInsert);\\n require(denominator != uint96(0), \\\"Inserting zero is not supported\\\");\\n require(\\n elementToInsert != QUEUE_START && elementToInsert != QUEUE_END,\\n \\\"Inserting element is not valid\\\"\\n );\\n if (contains(self, elementToInsert)) {\\n return false;\\n }\\n if (\\n elementBeforeNewOne != QUEUE_START &&\\n self.prevMap[elementBeforeNewOne] == bytes32(0)\\n ) {\\n return false;\\n }\\n if (!elementBeforeNewOne.smallerThan(elementToInsert)) {\\n return false;\\n }\\n\\n // `elementBeforeNewOne` might have been removed during the time it\\n // took to the transaction calling this function to be mined, so\\n // the new order cannot be appended directly to this. We follow the\\n // history of previous links backwards until we find an element in\\n // the list from which to start our search.\\n // Note that following the link backwards returns elements that are\\n // before `elementBeforeNewOne` in sorted order.\\n while (self.nextMap[elementBeforeNewOne] == bytes32(0)) {\\n elementBeforeNewOne = self.prevMap[elementBeforeNewOne];\\n }\\n\\n // `elementBeforeNewOne` belongs now to the linked list. We search the\\n // largest entry that is smaller than the element to insert.\\n bytes32 previous;\\n bytes32 current = elementBeforeNewOne;\\n do {\\n previous = current;\\n current = self.nextMap[current];\\n } while (current.smallerThan(elementToInsert));\\n // Note: previous < elementToInsert < current\\n self.nextMap[previous] = elementToInsert;\\n self.prevMap[current] = elementToInsert;\\n self.prevMap[elementToInsert] = previous;\\n self.nextMap[elementToInsert] = current;\\n\\n return true;\\n }\\n\\n /// The element is removed from the linked list, but the node retains\\n /// information on which predecessor it had, so that a node in the chain\\n /// can be reached by following the predecessor chain of deleted elements.\\n function removeKeepHistory(Data storage self, bytes32 elementToRemove)\\n internal\\n returns (bool)\\n {\\n if (!contains(self, elementToRemove)) {\\n return false;\\n }\\n bytes32 previousElement = self.prevMap[elementToRemove];\\n bytes32 nextElement = self.nextMap[elementToRemove];\\n self.nextMap[previousElement] = nextElement;\\n self.prevMap[nextElement] = previousElement;\\n self.nextMap[elementToRemove] = bytes32(0);\\n return true;\\n }\\n\\n /// Remove an element from the chain, clearing all related storage.\\n /// Note that no elements should be inserted using as a reference point a\\n /// node deleted after calling `remove`, since an element in the `prev`\\n /// chain might be missing.\\n function remove(Data storage self, bytes32 elementToRemove)\\n internal\\n returns (bool)\\n {\\n bool result = removeKeepHistory(self, elementToRemove);\\n if (result) {\\n self.prevMap[elementToRemove] = bytes32(0);\\n }\\n return result;\\n }\\n\\n function contains(Data storage self, bytes32 value)\\n internal\\n view\\n returns (bool)\\n {\\n if (value == QUEUE_START) {\\n return false;\\n }\\n // Note: QUEUE_END is not contained in the list since it has no\\n // successor.\\n return self.nextMap[value] != bytes32(0);\\n }\\n\\n // @dev orders are ordered by\\n // 1. their price - buyAmount/sellAmount\\n // 2. by the sellAmount\\n // 3. their userId,\\n function smallerThan(bytes32 orderLeft, bytes32 orderRight)\\n internal\\n pure\\n returns (bool)\\n {\\n (\\n uint64 userIdLeft,\\n uint96 priceNumeratorLeft,\\n uint96 priceDenominatorLeft\\n ) = decodeOrder(orderLeft);\\n (\\n uint64 userIdRight,\\n uint96 priceNumeratorRight,\\n uint96 priceDenominatorRight\\n ) = decodeOrder(orderRight);\\n\\n if (\\n priceNumeratorLeft.mul(priceDenominatorRight) <\\n priceNumeratorRight.mul(priceDenominatorLeft)\\n ) return true;\\n if (\\n priceNumeratorLeft.mul(priceDenominatorRight) >\\n priceNumeratorRight.mul(priceDenominatorLeft)\\n ) return false;\\n\\n if (priceNumeratorLeft < priceNumeratorRight) return true;\\n if (priceNumeratorLeft > priceNumeratorRight) return false;\\n require(\\n userIdLeft != userIdRight,\\n \\\"user is not allowed to place same order twice\\\"\\n );\\n if (userIdLeft < userIdRight) {\\n return true;\\n }\\n return false;\\n }\\n\\n function first(Data storage self) internal view returns (bytes32) {\\n require(!isEmpty(self), \\\"Trying to get first from empty set\\\");\\n return self.nextMap[QUEUE_START];\\n }\\n\\n function next(Data storage self, bytes32 value)\\n internal\\n view\\n returns (bytes32)\\n {\\n require(value != QUEUE_END, \\\"Trying to get next of last element\\\");\\n bytes32 nextElement = self.nextMap[value];\\n require(\\n nextElement != bytes32(0),\\n \\\"Trying to get next of non-existent element\\\"\\n );\\n return nextElement;\\n }\\n\\n function decodeOrder(bytes32 _orderData)\\n internal\\n pure\\n returns (\\n uint64 userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n )\\n {\\n // Note: converting to uint discards the binary digits that do not fit\\n // the type.\\n userId = uint64(uint256(_orderData) >> 192);\\n buyAmount = uint96(uint256(_orderData) >> 96);\\n sellAmount = uint96(uint256(_orderData));\\n }\\n\\n function encodeOrder(\\n uint64 userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n ) internal pure returns (bytes32) {\\n return\\n bytes32(\\n (uint256(userId) << 192) +\\n (uint256(buyAmount) << 96) +\\n uint256(sellAmount)\\n );\\n }\\n}\\n\",\"keccak256\":\"0xdcc090564f29439c38f4eb85115ba9ba4479a7494cd9e877fdc2b6d19b94d574\"},\"contracts/libraries/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Logic was copied and modified from here: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/SafeCast.sol\\n */\\nlibrary SafeCast {\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value < 2**96, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value < 2**64, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n}\\n\",\"keccak256\":\"0x9f12a3c511cd8ea260bc8faa7d2e4d59a823328ef07c26af506385aa3e92b200\",\"license\":\"MIT\"},\"contracts/wrappers/DepositAndPlaceOrder.sol\":{\"content\":\"pragma solidity >=0.6.8;\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"../EasyAuction.sol\\\";\\nimport \\\"../interfaces/IWETH.sol\\\";\\n\\ncontract DepositAndPlaceOrder {\\n EasyAuction public immutable easyAuction;\\n IWETH public immutable nativeTokenWrapper;\\n\\n constructor(address easyAuctionAddress, address _nativeTokenWrapper)\\n public\\n {\\n nativeTokenWrapper = IWETH(_nativeTokenWrapper);\\n easyAuction = EasyAuction(easyAuctionAddress);\\n IERC20(_nativeTokenWrapper).approve(easyAuctionAddress, uint256(-1));\\n }\\n\\n function depositAndPlaceOrder(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmounts,\\n bytes32[] memory _prevSellOrders,\\n bytes calldata allowListCallData\\n ) external payable returns (uint64 userId) {\\n uint96[] memory sellAmounts = new uint96[](1);\\n require(msg.value < 2**96, \\\"too much value sent\\\");\\n nativeTokenWrapper.deposit{value: msg.value}();\\n sellAmounts[0] = uint96(msg.value);\\n return\\n easyAuction.placeSellOrdersOnBehalf(\\n auctionId,\\n _minBuyAmounts,\\n sellAmounts,\\n _prevSellOrders,\\n allowListCallData,\\n msg.sender\\n );\\n }\\n}\\n\",\"keccak256\":\"0x630cccdf9987d8ef2abaf9556e3f8508f79a6f3067a0db33966bfa73212b9777\"}},\"version\":1}", + "bytecode": "0x60c060405234801561001057600080fd5b506040516108303803806108308339818101604052604081101561003357600080fd5b8101908080519060200190929190805190602001909291905050508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b815250508173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1663095ea7b3837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561014d57600080fd5b505af1158015610161573d6000803e3d6000fd5b505050506040513d602081101561017757600080fd5b810190808051906020019092919050505050505060805160601c60a05160601c6106726101be6000398061037a528061061a525080610286528061043352506106726000f3fe6080604052600436106100345760003560e01c8063537a338114610039578063eb30ee571461007a578063f9ea29cb14610243575b600080fd5b34801561004557600080fd5b5061004e610284565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102236004803603608081101561009057600080fd5b8101908080359060200190929190803590602001906401000000008111156100b757600080fd5b8201836020820111156100c957600080fd5b803590602001918460208302840111640100000000831117156100eb57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561014b57600080fd5b82018360208201111561015d57600080fd5b8035906020019184602083028401116401000000008311171561017f57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156101df57600080fd5b8201836020820111156101f157600080fd5b8035906020019184600183028401116401000000008311171561021357600080fd5b90919293919293905050506102a8565b604051808267ffffffffffffffff16815260200191505060405180910390f35b34801561024f57600080fd5b50610258610618565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b60006060600167ffffffffffffffff811180156102c457600080fd5b506040519080825280602002602001820160405280156102f35781602001602082028036833780820191505090505b5090506c010000000000000000000000003410610378576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f746f6f206d7563682076616c75652073656e740000000000000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103e057600080fd5b505af11580156103f4573d6000803e3d6000fd5b5050505050348160008151811061040757fe5b60200260200101906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ec20d0bb888884898989336040518863ffffffff1660e01b815260040180888152602001806020018060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff16815260200185810385528b818151815260200191508051906020019060200280838360005b838110156104f45780820151818401526020810190506104d9565b5050505090500185810384528a818151815260200191508051906020019060200280838360005b8381101561053657808201518184015260208101905061051b565b50505050905001858103835289818151815260200191508051906020019060200280838360005b8381101561057857808201518184015260208101905061055d565b505050509050018581038252888882818152602001925080828437600081840152601f19601f8201169050808301925050509b505050505050505050505050602060405180830381600087803b1580156105d157600080fd5b505af11580156105e5573d6000803e3d6000fd5b505050506040513d60208110156105fb57600080fd5b810190808051906020019092919050505091505095945050505050565b7f00000000000000000000000000000000000000000000000000000000000000008156fea2646970667358221220307188712492dd1f234d11623e8220cf260536df33f3c198b390862c3e6e006664736f6c634300060c0033", + "deployedBytecode": "0x6080604052600436106100345760003560e01c8063537a338114610039578063eb30ee571461007a578063f9ea29cb14610243575b600080fd5b34801561004557600080fd5b5061004e610284565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6102236004803603608081101561009057600080fd5b8101908080359060200190929190803590602001906401000000008111156100b757600080fd5b8201836020820111156100c957600080fd5b803590602001918460208302840111640100000000831117156100eb57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561014b57600080fd5b82018360208201111561015d57600080fd5b8035906020019184602083028401116401000000008311171561017f57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156101df57600080fd5b8201836020820111156101f157600080fd5b8035906020019184600183028401116401000000008311171561021357600080fd5b90919293919293905050506102a8565b604051808267ffffffffffffffff16815260200191505060405180910390f35b34801561024f57600080fd5b50610258610618565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b60006060600167ffffffffffffffff811180156102c457600080fd5b506040519080825280602002602001820160405280156102f35781602001602082028036833780820191505090505b5090506c010000000000000000000000003410610378576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f746f6f206d7563682076616c75652073656e740000000000000000000000000081525060200191505060405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103e057600080fd5b505af11580156103f4573d6000803e3d6000fd5b5050505050348160008151811061040757fe5b60200260200101906bffffffffffffffffffffffff1690816bffffffffffffffffffffffff16815250507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ec20d0bb888884898989336040518863ffffffff1660e01b815260040180888152602001806020018060200180602001806020018673ffffffffffffffffffffffffffffffffffffffff16815260200185810385528b818151815260200191508051906020019060200280838360005b838110156104f45780820151818401526020810190506104d9565b5050505090500185810384528a818151815260200191508051906020019060200280838360005b8381101561053657808201518184015260208101905061051b565b50505050905001858103835289818151815260200191508051906020019060200280838360005b8381101561057857808201518184015260208101905061055d565b505050509050018581038252888882818152602001925080828437600081840152601f19601f8201169050808301925050509b505050505050505050505050602060405180830381600087803b1580156105d157600080fd5b505af11580156105e5573d6000803e3d6000fd5b505050506040513d60208110156105fb57600080fd5b810190808051906020019092919050505091505095945050505050565b7f00000000000000000000000000000000000000000000000000000000000000008156fea2646970667358221220307188712492dd1f234d11623e8220cf260536df33f3c198b390862c3e6e006664736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/binancesmartchaintestnet/EasyAuction.json b/deployments/binancesmartchaintestnet/EasyAuction.json new file mode 100644 index 0000000..d284108 --- /dev/null +++ b/deployments/binancesmartchaintestnet/EasyAuction.json @@ -0,0 +1,1255 @@ +{ + "address": "0x231F3Fd7c3E3C9a2c8A03B72132c31241DF0a26C", + "abi": [ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "soldAuctioningTokens", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "soldBiddingTokens", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "clearingPriceOrder", + "type": "bytes32" + } + ], + "name": "AuctionCleared", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "userId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "buyAmount", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "sellAmount", + "type": "uint96" + } + ], + "name": "CancellationSellOrder", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "userId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "buyAmount", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "sellAmount", + "type": "uint96" + } + ], + "name": "ClaimedFromOrder", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "_auctioningToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "contract IERC20", + "name": "_biddingToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "orderCancellationEndDate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "auctionEndDate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "userId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "_auctionedSellAmount", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "_minBuyAmount", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "minimumBiddingAmountPerOrder", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "minFundingThreshold", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "allowListContract", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "allowListData", + "type": "bytes" + } + ], + "name": "NewAuction", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint64", + "name": "userId", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "buyAmount", + "type": "uint96" + }, + { + "indexed": false, + "internalType": "uint96", + "name": "sellAmount", + "type": "uint96" + } + ], + "name": "NewSellOrder", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "userId", + "type": "uint64" + }, + { + "indexed": true, + "internalType": "address", + "name": "userAddress", + "type": "address" + } + ], + "name": "NewUser", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint64", + "name": "userId", + "type": "uint64" + } + ], + "name": "UserRegistration", + "type": "event" + }, + { + "inputs": [], + "name": "FEE_DENOMINATOR", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "auctionAccessData", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "auctionAccessManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "auctionCounter", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "auctionData", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "auctioningToken", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "biddingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "orderCancellationEndDate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "auctionEndDate", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "initialAuctionOrder", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "minimumBiddingAmountPerOrder", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "interimSumBidAmount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "interimOrder", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "clearingPriceOrder", + "type": "bytes32" + }, + { + "internalType": "uint96", + "name": "volumeClearingPriceOrder", + "type": "uint96" + }, + { + "internalType": "bool", + "name": "minFundingThresholdNotReached", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isAtomicClosureAllowed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "feeNumerator", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFundingThreshold", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "_sellOrders", + "type": "bytes32[]" + } + ], + "name": "cancelSellOrders", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "orders", + "type": "bytes32[]" + } + ], + "name": "claimFromParticipantOrder", + "outputs": [ + { + "internalType": "uint256", + "name": "sumAuctioningTokenAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "sumBiddingTokenAmount", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "order", + "type": "bytes32" + } + ], + "name": "containsOrder", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeNumerator", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "feeReceiverUserId", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + } + ], + "name": "getSecondsRemainingInBatch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "getUserId", + "outputs": [ + { + "internalType": "uint64", + "name": "userId", + "type": "uint64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "_auctioningToken", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "_biddingToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "orderCancellationEndDate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "auctionEndDate", + "type": "uint256" + }, + { + "internalType": "uint96", + "name": "_auctionedSellAmount", + "type": "uint96" + }, + { + "internalType": "uint96", + "name": "_minBuyAmount", + "type": "uint96" + }, + { + "internalType": "uint256", + "name": "minimumBiddingAmountPerOrder", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "minFundingThreshold", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "isAtomicClosureAllowed", + "type": "bool" + }, + { + "internalType": "address", + "name": "accessManagerContract", + "type": "address" + }, + { + "internalType": "bytes", + "name": "accessManagerContractData", + "type": "bytes" + } + ], + "name": "initiateAuction", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "numUsers", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "internalType": "uint96[]", + "name": "_minBuyAmounts", + "type": "uint96[]" + }, + { + "internalType": "uint96[]", + "name": "_sellAmounts", + "type": "uint96[]" + }, + { + "internalType": "bytes32[]", + "name": "_prevSellOrders", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "allowListCallData", + "type": "bytes" + } + ], + "name": "placeSellOrders", + "outputs": [ + { + "internalType": "uint64", + "name": "userId", + "type": "uint64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "internalType": "uint96[]", + "name": "_minBuyAmounts", + "type": "uint96[]" + }, + { + "internalType": "uint96[]", + "name": "_sellAmounts", + "type": "uint96[]" + }, + { + "internalType": "bytes32[]", + "name": "_prevSellOrders", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "allowListCallData", + "type": "bytes" + }, + { + "internalType": "address", + "name": "orderSubmitter", + "type": "address" + } + ], + "name": "placeSellOrdersOnBehalf", + "outputs": [ + { + "internalType": "uint64", + "name": "userId", + "type": "uint64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "iterationSteps", + "type": "uint256" + } + ], + "name": "precalculateSellAmountSum", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "registerUser", + "outputs": [ + { + "internalType": "uint64", + "name": "userId", + "type": "uint64" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "newFeeNumerator", + "type": "uint256" + }, + { + "internalType": "address", + "name": "newfeeReceiverAddress", + "type": "address" + } + ], + "name": "setFeeParameters", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + } + ], + "name": "settleAuction", + "outputs": [ + { + "internalType": "bytes32", + "name": "clearingOrder", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "auctionId", + "type": "uint256" + }, + { + "internalType": "uint96[]", + "name": "_minBuyAmount", + "type": "uint96[]" + }, + { + "internalType": "uint96[]", + "name": "_sellAmount", + "type": "uint96[]" + }, + { + "internalType": "bytes32[]", + "name": "_prevSellOrder", + "type": "bytes32[]" + }, + { + "internalType": "bytes", + "name": "allowListCallData", + "type": "bytes" + } + ], + "name": "settleAuctionAtomically", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x81669823fe6d170ee4ff90a74298528b1e133cb097c0772c7838fe258f4a433e", + "receipt": { + "to": null, + "from": "0x1F90D0754A6822A5d9622600A1b52893d93Bb646", + "contractAddress": "0x231F3Fd7c3E3C9a2c8A03B72132c31241DF0a26C", + "transactionIndex": 6, + "gasUsed": "5135197", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000040000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000040000000000000000000000000000000000000000000000000", + "blockHash": "0x88aca28386edf081790801b6bdcb7cc671d64e3ae72a9ed7c16d5528558ad390", + "transactionHash": "0x81669823fe6d170ee4ff90a74298528b1e133cb097c0772c7838fe258f4a433e", + "logs": [ + { + "transactionIndex": 6, + "blockNumber": 29675176, + "transactionHash": "0x81669823fe6d170ee4ff90a74298528b1e133cb097c0772c7838fe258f4a433e", + "address": "0x231F3Fd7c3E3C9a2c8A03B72132c31241DF0a26C", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000001f90d0754a6822a5d9622600a1b52893d93bb646" + ], + "data": "0x", + "logIndex": 31, + "blockHash": "0x88aca28386edf081790801b6bdcb7cc671d64e3ae72a9ed7c16d5528558ad390" + } + ], + "blockNumber": 29675176, + "cumulativeGasUsed": "6095380", + "status": 1, + "byzantium": true + }, + "args": [], + "numDeployments": 1, + "solcInputHash": "a81c49f8848cbbe2b3d955ebaff2de99", + "metadata": "{\"compiler\":{\"version\":\"0.6.12+commit.27d51765\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"soldAuctioningTokens\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"soldBiddingTokens\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"clearingPriceOrder\",\"type\":\"bytes32\"}],\"name\":\"AuctionCleared\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"userId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"buyAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"sellAmount\",\"type\":\"uint96\"}],\"name\":\"CancellationSellOrder\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"userId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"buyAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"sellAmount\",\"type\":\"uint96\"}],\"name\":\"ClaimedFromOrder\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"_auctioningToken\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"contract IERC20\",\"name\":\"_biddingToken\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"orderCancellationEndDate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"auctionEndDate\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"userId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"_auctionedSellAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"_minBuyAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"minimumBiddingAmountPerOrder\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"minFundingThreshold\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"allowListContract\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"allowListData\",\"type\":\"bytes\"}],\"name\":\"NewAuction\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"userId\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"buyAmount\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"sellAmount\",\"type\":\"uint96\"}],\"name\":\"NewSellOrder\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"userId\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"userAddress\",\"type\":\"address\"}],\"name\":\"NewUser\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"previousOwner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"userId\",\"type\":\"uint64\"}],\"name\":\"UserRegistration\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"FEE_DENOMINATOR\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"auctionAccessData\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"auctionAccessManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"auctionCounter\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"auctionData\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"auctioningToken\",\"type\":\"address\"},{\"internalType\":\"contract IERC20\",\"name\":\"biddingToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"orderCancellationEndDate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"auctionEndDate\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"initialAuctionOrder\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"minimumBiddingAmountPerOrder\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"interimSumBidAmount\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"interimOrder\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"clearingPriceOrder\",\"type\":\"bytes32\"},{\"internalType\":\"uint96\",\"name\":\"volumeClearingPriceOrder\",\"type\":\"uint96\"},{\"internalType\":\"bool\",\"name\":\"minFundingThresholdNotReached\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"isAtomicClosureAllowed\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"feeNumerator\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minFundingThreshold\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"_sellOrders\",\"type\":\"bytes32[]\"}],\"name\":\"cancelSellOrders\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"orders\",\"type\":\"bytes32[]\"}],\"name\":\"claimFromParticipantOrder\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"sumAuctioningTokenAmount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"sumBiddingTokenAmount\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"order\",\"type\":\"bytes32\"}],\"name\":\"containsOrder\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeNumerator\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeReceiverUserId\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"}],\"name\":\"getSecondsRemainingInBatch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"getUserId\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"userId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"_auctioningToken\",\"type\":\"address\"},{\"internalType\":\"contract IERC20\",\"name\":\"_biddingToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"orderCancellationEndDate\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"auctionEndDate\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"_auctionedSellAmount\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"_minBuyAmount\",\"type\":\"uint96\"},{\"internalType\":\"uint256\",\"name\":\"minimumBiddingAmountPerOrder\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"minFundingThreshold\",\"type\":\"uint256\"},{\"internalType\":\"bool\",\"name\":\"isAtomicClosureAllowed\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"accessManagerContract\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"accessManagerContractData\",\"type\":\"bytes\"}],\"name\":\"initiateAuction\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"numUsers\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"internalType\":\"uint96[]\",\"name\":\"_minBuyAmounts\",\"type\":\"uint96[]\"},{\"internalType\":\"uint96[]\",\"name\":\"_sellAmounts\",\"type\":\"uint96[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_prevSellOrders\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"allowListCallData\",\"type\":\"bytes\"}],\"name\":\"placeSellOrders\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"userId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"internalType\":\"uint96[]\",\"name\":\"_minBuyAmounts\",\"type\":\"uint96[]\"},{\"internalType\":\"uint96[]\",\"name\":\"_sellAmounts\",\"type\":\"uint96[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_prevSellOrders\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"allowListCallData\",\"type\":\"bytes\"},{\"internalType\":\"address\",\"name\":\"orderSubmitter\",\"type\":\"address\"}],\"name\":\"placeSellOrdersOnBehalf\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"userId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"iterationSteps\",\"type\":\"uint256\"}],\"name\":\"precalculateSellAmountSum\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"registerUser\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"userId\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"newFeeNumerator\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newfeeReceiverAddress\",\"type\":\"address\"}],\"name\":\"setFeeParameters\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"}],\"name\":\"settleAuction\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"clearingOrder\",\"type\":\"bytes32\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"auctionId\",\"type\":\"uint256\"},{\"internalType\":\"uint96[]\",\"name\":\"_minBuyAmount\",\"type\":\"uint96[]\"},{\"internalType\":\"uint96[]\",\"name\":\"_sellAmount\",\"type\":\"uint96[]\"},{\"internalType\":\"bytes32[]\",\"name\":\"_prevSellOrder\",\"type\":\"bytes32[]\"},{\"internalType\":\"bytes\",\"name\":\"allowListCallData\",\"type\":\"bytes\"}],\"name\":\"settleAuctionAtomically\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"renounceOwnership()\":{\"details\":\"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.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/EasyAuction.sol\":\"EasyAuction\"},\"evmVersion\":\"istanbul\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":false,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/GSN/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/*\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with GSN meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address payable) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes memory) {\\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0x8d3cb350f04ff49cfb10aef08d87f19dcbaecc8027b0bed12f3275cd12f38cf0\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"../GSN/Context.sol\\\";\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor () internal {\\n address msgSender = _msgSender();\\n _owner = msgSender;\\n emit OwnershipTransferred(address(0), msgSender);\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view returns (address) {\\n return _owner;\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n require(_owner == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\n _;\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions anymore. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby removing any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n emit OwnershipTransferred(_owner, address(0));\\n _owner = address(0);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n emit OwnershipTransferred(_owner, newOwner);\\n _owner = newOwner;\\n }\\n}\\n\",\"keccak256\":\"0xf7c39c7e6d06ed3bda90cfefbcbf2ddc32c599c3d6721746546ad64946efccaa\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow, so we distribute\\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\\n }\\n}\\n\",\"keccak256\":\"0x363bd3b45201f07c9b71c2edc96533468cf14a3d029fabd82fddceb1eb3ebd9c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/math/SafeMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\\n * checks.\\n *\\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\\n * in bugs, because programmers usually assume that an overflow raises an\\n * error, which is the standard behavior in high level programming languages.\\n * `SafeMath` restores this intuition by reverting the transaction when an\\n * operation overflows.\\n *\\n * Using this library instead of the unchecked operations eliminates an entire\\n * class of bugs, so it's recommended to use it always.\\n */\\nlibrary SafeMath {\\n /**\\n * @dev Returns the addition of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `+` operator.\\n *\\n * Requirements:\\n *\\n * - Addition cannot overflow.\\n */\\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\\n uint256 c = a + b;\\n require(c >= a, \\\"SafeMath: addition overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\\n return sub(a, b, \\\"SafeMath: subtraction overflow\\\");\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\\n * overflow (when the result is negative).\\n *\\n * Counterpart to Solidity's `-` operator.\\n *\\n * Requirements:\\n *\\n * - Subtraction cannot overflow.\\n */\\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b <= a, errorMessage);\\n uint256 c = a - b;\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, reverting on\\n * overflow.\\n *\\n * Counterpart to Solidity's `*` operator.\\n *\\n * Requirements:\\n *\\n * - Multiplication cannot overflow.\\n */\\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) {\\n return 0;\\n }\\n\\n uint256 c = a * b;\\n require(c / a == b, \\\"SafeMath: multiplication overflow\\\");\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\\n return div(a, b, \\\"SafeMath: division by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\\n * division by zero. The result is rounded towards zero.\\n *\\n * Counterpart to Solidity's `/` operator. Note: this function uses a\\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\\n * uses an invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b > 0, errorMessage);\\n uint256 c = a / b;\\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\\n\\n return c;\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\\n return mod(a, b, \\\"SafeMath: modulo by zero\\\");\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\\n * Reverts with custom message when dividing by zero.\\n *\\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\\n * opcode (which leaves remaining gas untouched) while Solidity uses an\\n * invalid opcode to revert (consuming all remaining gas).\\n *\\n * Requirements:\\n *\\n * - The divisor cannot be zero.\\n */\\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\\n require(b != 0, errorMessage);\\n return a % b;\\n }\\n}\\n\",\"keccak256\":\"0x3b21f2c8d626de3b9925ae33e972d8bf5c8b1bffb3f4ee94daeed7d0679036e6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x5f02220344881ce43204ae4a6281145a67bc52c2bb1290a791857df3d19d78f5\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"../../math/SafeMath.sol\\\";\\nimport \\\"../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using SafeMath for uint256;\\n using Address for address;\\n\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n // solhint-disable-next-line max-line-length\\n require((value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \\\"SafeERC20: decreased allowance below zero\\\");\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) { // Return data is optional\\n // solhint-disable-next-line max-line-length\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0xf12dfbe97e6276980b83d2830bb0eb75e0cf4f3e626c2471137f82158ae6a0fc\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.2 <0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n // solhint-disable-next-line no-inline-assembly\\n assembly { size := extcodesize(account) }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\\n (bool success, ) = recipient.call{ value: amount }(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain`call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n // solhint-disable-next-line avoid-low-level-calls\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return _verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n // solhint-disable-next-line no-inline-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0xa6a15ddddcbf29d2922a1e0d4151b5d2d33da24b93cc9ebc12390e0d855532f8\",\"license\":\"MIT\"},\"contracts/EasyAuction.sol\":{\"content\":\"pragma solidity >=0.6.8;\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\nimport \\\"./libraries/IterableOrderedOrderSet.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\nimport \\\"./libraries/IdToAddressBiMap.sol\\\";\\nimport \\\"./libraries/SafeCast.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport \\\"./interfaces/AllowListVerifier.sol\\\";\\n\\ncontract EasyAuction is Ownable {\\n using SafeERC20 for IERC20;\\n using SafeMath for uint64;\\n using SafeMath for uint96;\\n using SafeMath for uint256;\\n using SafeCast for uint256;\\n using IterableOrderedOrderSet for IterableOrderedOrderSet.Data;\\n using IterableOrderedOrderSet for bytes32;\\n using IdToAddressBiMap for IdToAddressBiMap.Data;\\n\\n modifier atStageOrderPlacement(uint256 auctionId) {\\n require(\\n block.timestamp < auctionData[auctionId].auctionEndDate,\\n \\\"no longer in order placement phase\\\"\\n );\\n _;\\n }\\n\\n modifier atStageOrderPlacementAndCancelation(uint256 auctionId) {\\n require(\\n block.timestamp < auctionData[auctionId].orderCancellationEndDate,\\n \\\"no longer in order placement and cancelation phase\\\"\\n );\\n _;\\n }\\n\\n modifier atStageSolutionSubmission(uint256 auctionId) {\\n {\\n uint256 auctionEndDate = auctionData[auctionId].auctionEndDate;\\n require(\\n auctionEndDate != 0 &&\\n block.timestamp >= auctionEndDate &&\\n auctionData[auctionId].clearingPriceOrder == bytes32(0),\\n \\\"Auction not in solution submission phase\\\"\\n );\\n }\\n _;\\n }\\n\\n modifier atStageFinished(uint256 auctionId) {\\n require(\\n auctionData[auctionId].clearingPriceOrder != bytes32(0),\\n \\\"Auction not yet finished\\\"\\n );\\n _;\\n }\\n\\n event NewSellOrder(\\n uint256 indexed auctionId,\\n uint64 indexed userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n );\\n event CancellationSellOrder(\\n uint256 indexed auctionId,\\n uint64 indexed userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n );\\n event ClaimedFromOrder(\\n uint256 indexed auctionId,\\n uint64 indexed userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n );\\n event NewUser(uint64 indexed userId, address indexed userAddress);\\n event NewAuction(\\n uint256 indexed auctionId,\\n IERC20 indexed _auctioningToken,\\n IERC20 indexed _biddingToken,\\n uint256 orderCancellationEndDate,\\n uint256 auctionEndDate,\\n uint64 userId,\\n uint96 _auctionedSellAmount,\\n uint96 _minBuyAmount,\\n uint256 minimumBiddingAmountPerOrder,\\n uint256 minFundingThreshold,\\n address allowListContract,\\n bytes allowListData\\n );\\n event AuctionCleared(\\n uint256 indexed auctionId,\\n uint96 soldAuctioningTokens,\\n uint96 soldBiddingTokens,\\n bytes32 clearingPriceOrder\\n );\\n event UserRegistration(address indexed user, uint64 userId);\\n\\n struct AuctionData {\\n IERC20 auctioningToken;\\n IERC20 biddingToken;\\n uint256 orderCancellationEndDate;\\n uint256 auctionEndDate;\\n bytes32 initialAuctionOrder;\\n uint256 minimumBiddingAmountPerOrder;\\n uint256 interimSumBidAmount;\\n bytes32 interimOrder;\\n bytes32 clearingPriceOrder;\\n uint96 volumeClearingPriceOrder;\\n bool minFundingThresholdNotReached;\\n bool isAtomicClosureAllowed;\\n uint256 feeNumerator;\\n uint256 minFundingThreshold;\\n }\\n mapping(uint256 => IterableOrderedOrderSet.Data) internal sellOrders;\\n mapping(uint256 => AuctionData) public auctionData;\\n mapping(uint256 => address) public auctionAccessManager;\\n mapping(uint256 => bytes) public auctionAccessData;\\n\\n IdToAddressBiMap.Data private registeredUsers;\\n uint64 public numUsers;\\n uint256 public auctionCounter;\\n\\n constructor() public Ownable() {}\\n\\n uint256 public feeNumerator = 0;\\n uint256 public constant FEE_DENOMINATOR = 1000;\\n uint64 public feeReceiverUserId = 1;\\n\\n function setFeeParameters(\\n uint256 newFeeNumerator,\\n address newfeeReceiverAddress\\n ) public onlyOwner() {\\n require(\\n newFeeNumerator <= 15,\\n \\\"Fee is not allowed to be set higher than 1.5%\\\"\\n );\\n // caution: for currently running auctions, the feeReceiverUserId is changing as well.\\n feeReceiverUserId = getUserId(newfeeReceiverAddress);\\n feeNumerator = newFeeNumerator;\\n }\\n\\n // @dev: function to intiate a new auction\\n // Warning: In case the auction is expected to raise more than\\n // 2^96 units of the biddingToken, don't start the auction, as\\n // it will not be settlable. This corresponds to about 79\\n // billion DAI.\\n //\\n // Prices between biddingToken and auctioningToken are expressed by a\\n // fraction whose components are stored as uint96.\\n function initiateAuction(\\n IERC20 _auctioningToken,\\n IERC20 _biddingToken,\\n uint256 orderCancellationEndDate,\\n uint256 auctionEndDate,\\n uint96 _auctionedSellAmount,\\n uint96 _minBuyAmount,\\n uint256 minimumBiddingAmountPerOrder,\\n uint256 minFundingThreshold,\\n bool isAtomicClosureAllowed,\\n address accessManagerContract,\\n bytes memory accessManagerContractData\\n ) public returns (uint256) {\\n // withdraws sellAmount + fees\\n _auctioningToken.safeTransferFrom(\\n msg.sender,\\n address(this),\\n _auctionedSellAmount.mul(FEE_DENOMINATOR.add(feeNumerator)).div(\\n FEE_DENOMINATOR\\n ) //[0]\\n );\\n require(_auctionedSellAmount > 0, \\\"cannot auction zero tokens\\\");\\n require(_minBuyAmount > 0, \\\"tokens cannot be auctioned for free\\\");\\n require(\\n minimumBiddingAmountPerOrder > 0,\\n \\\"minimumBiddingAmountPerOrder is not allowed to be zero\\\"\\n );\\n require(\\n orderCancellationEndDate <= auctionEndDate,\\n \\\"time periods are not configured correctly\\\"\\n );\\n require(\\n auctionEndDate > block.timestamp,\\n \\\"auction end date must be in the future\\\"\\n );\\n auctionCounter = auctionCounter.add(1);\\n sellOrders[auctionCounter].initializeEmptyList();\\n uint64 userId = getUserId(msg.sender);\\n auctionData[auctionCounter] = AuctionData(\\n _auctioningToken,\\n _biddingToken,\\n orderCancellationEndDate,\\n auctionEndDate,\\n IterableOrderedOrderSet.encodeOrder(\\n userId,\\n _minBuyAmount,\\n _auctionedSellAmount\\n ),\\n minimumBiddingAmountPerOrder,\\n 0,\\n IterableOrderedOrderSet.QUEUE_START,\\n bytes32(0),\\n 0,\\n false,\\n isAtomicClosureAllowed,\\n feeNumerator,\\n minFundingThreshold\\n );\\n auctionAccessManager[auctionCounter] = accessManagerContract;\\n auctionAccessData[auctionCounter] = accessManagerContractData;\\n emit NewAuction(\\n auctionCounter,\\n _auctioningToken,\\n _biddingToken,\\n orderCancellationEndDate,\\n auctionEndDate,\\n userId,\\n _auctionedSellAmount,\\n _minBuyAmount,\\n minimumBiddingAmountPerOrder,\\n minFundingThreshold,\\n accessManagerContract,\\n accessManagerContractData\\n );\\n return auctionCounter;\\n }\\n\\n function placeSellOrders(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmounts,\\n uint96[] memory _sellAmounts,\\n bytes32[] memory _prevSellOrders,\\n bytes calldata allowListCallData\\n ) external atStageOrderPlacement(auctionId) returns (uint64 userId) {\\n return\\n _placeSellOrders(\\n auctionId,\\n _minBuyAmounts,\\n _sellAmounts,\\n _prevSellOrders,\\n allowListCallData,\\n msg.sender\\n );\\n }\\n\\n function placeSellOrdersOnBehalf(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmounts,\\n uint96[] memory _sellAmounts,\\n bytes32[] memory _prevSellOrders,\\n bytes calldata allowListCallData,\\n address orderSubmitter\\n ) external atStageOrderPlacement(auctionId) returns (uint64 userId) {\\n return\\n _placeSellOrders(\\n auctionId,\\n _minBuyAmounts,\\n _sellAmounts,\\n _prevSellOrders,\\n allowListCallData,\\n orderSubmitter\\n );\\n }\\n\\n function _placeSellOrders(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmounts,\\n uint96[] memory _sellAmounts,\\n bytes32[] memory _prevSellOrders,\\n bytes calldata allowListCallData,\\n address orderSubmitter\\n ) internal returns (uint64 userId) {\\n {\\n address allowListManager = auctionAccessManager[auctionId];\\n if (allowListManager != address(0)) {\\n require(\\n AllowListVerifier(allowListManager).isAllowed(\\n orderSubmitter,\\n auctionId,\\n allowListCallData\\n ) == AllowListVerifierHelper.MAGICVALUE,\\n \\\"user not allowed to place order\\\"\\n );\\n }\\n }\\n {\\n (\\n ,\\n uint96 buyAmountOfInitialAuctionOrder,\\n uint96 sellAmountOfInitialAuctionOrder\\n ) = auctionData[auctionId].initialAuctionOrder.decodeOrder();\\n for (uint256 i = 0; i < _minBuyAmounts.length; i++) {\\n require(\\n _minBuyAmounts[i].mul(buyAmountOfInitialAuctionOrder) <\\n sellAmountOfInitialAuctionOrder.mul(_sellAmounts[i]),\\n \\\"limit price not better than mimimal offer\\\"\\n );\\n }\\n }\\n uint256 sumOfSellAmounts = 0;\\n userId = getUserId(orderSubmitter);\\n uint256 minimumBiddingAmountPerOrder =\\n auctionData[auctionId].minimumBiddingAmountPerOrder;\\n for (uint256 i = 0; i < _minBuyAmounts.length; i++) {\\n require(\\n _minBuyAmounts[i] > 0,\\n \\\"_minBuyAmounts must be greater than 0\\\"\\n );\\n // orders should have a minimum bid size in order to limit the gas\\n // required to compute the final price of the auction.\\n require(\\n _sellAmounts[i] > minimumBiddingAmountPerOrder,\\n \\\"order too small\\\"\\n );\\n if (\\n sellOrders[auctionId].insert(\\n IterableOrderedOrderSet.encodeOrder(\\n userId,\\n _minBuyAmounts[i],\\n _sellAmounts[i]\\n ),\\n _prevSellOrders[i]\\n )\\n ) {\\n sumOfSellAmounts = sumOfSellAmounts.add(_sellAmounts[i]);\\n emit NewSellOrder(\\n auctionId,\\n userId,\\n _minBuyAmounts[i],\\n _sellAmounts[i]\\n );\\n }\\n }\\n auctionData[auctionId].biddingToken.safeTransferFrom(\\n msg.sender,\\n address(this),\\n sumOfSellAmounts\\n ); //[1]\\n }\\n\\n function cancelSellOrders(uint256 auctionId, bytes32[] memory _sellOrders)\\n public\\n atStageOrderPlacementAndCancelation(auctionId)\\n {\\n uint64 userId = getUserId(msg.sender);\\n uint256 claimableAmount = 0;\\n for (uint256 i = 0; i < _sellOrders.length; i++) {\\n // Note: we keep the back pointer of the deleted element so that\\n // it can be used as a reference point to insert a new node.\\n bool success =\\n sellOrders[auctionId].removeKeepHistory(_sellOrders[i]);\\n if (success) {\\n (\\n uint64 userIdOfIter,\\n uint96 buyAmountOfIter,\\n uint96 sellAmountOfIter\\n ) = _sellOrders[i].decodeOrder();\\n require(\\n userIdOfIter == userId,\\n \\\"Only the user can cancel his orders\\\"\\n );\\n claimableAmount = claimableAmount.add(sellAmountOfIter);\\n emit CancellationSellOrder(\\n auctionId,\\n userId,\\n buyAmountOfIter,\\n sellAmountOfIter\\n );\\n }\\n }\\n auctionData[auctionId].biddingToken.safeTransfer(\\n msg.sender,\\n claimableAmount\\n ); //[2]\\n }\\n\\n function precalculateSellAmountSum(\\n uint256 auctionId,\\n uint256 iterationSteps\\n ) public atStageSolutionSubmission(auctionId) {\\n (, , uint96 auctioneerSellAmount) =\\n auctionData[auctionId].initialAuctionOrder.decodeOrder();\\n uint256 sumBidAmount = auctionData[auctionId].interimSumBidAmount;\\n bytes32 iterOrder = auctionData[auctionId].interimOrder;\\n\\n for (uint256 i = 0; i < iterationSteps; i++) {\\n iterOrder = sellOrders[auctionId].next(iterOrder);\\n (, , uint96 sellAmountOfIter) = iterOrder.decodeOrder();\\n sumBidAmount = sumBidAmount.add(sellAmountOfIter);\\n }\\n\\n require(\\n iterOrder != IterableOrderedOrderSet.QUEUE_END,\\n \\\"reached end of order list\\\"\\n );\\n\\n // it is checked that not too many iteration steps were taken:\\n // require that the sum of SellAmounts times the price of the last order\\n // is not more than initially sold amount\\n (, uint96 buyAmountOfIter, uint96 sellAmountOfIter) =\\n iterOrder.decodeOrder();\\n require(\\n sumBidAmount.mul(buyAmountOfIter) <\\n auctioneerSellAmount.mul(sellAmountOfIter),\\n \\\"too many orders summed up\\\"\\n );\\n\\n auctionData[auctionId].interimSumBidAmount = sumBidAmount;\\n auctionData[auctionId].interimOrder = iterOrder;\\n }\\n\\n function settleAuctionAtomically(\\n uint256 auctionId,\\n uint96[] memory _minBuyAmount,\\n uint96[] memory _sellAmount,\\n bytes32[] memory _prevSellOrder,\\n bytes calldata allowListCallData\\n ) public atStageSolutionSubmission(auctionId) {\\n require(\\n auctionData[auctionId].isAtomicClosureAllowed,\\n \\\"not allowed to settle auction atomically\\\"\\n );\\n require(\\n _minBuyAmount.length == 1 && _sellAmount.length == 1,\\n \\\"Only one order can be placed atomically\\\"\\n );\\n uint64 userId = getUserId(msg.sender);\\n require(\\n auctionData[auctionId].interimOrder.smallerThan(\\n IterableOrderedOrderSet.encodeOrder(\\n userId,\\n _minBuyAmount[0],\\n _sellAmount[0]\\n )\\n ),\\n \\\"precalculateSellAmountSum is already too advanced\\\"\\n );\\n _placeSellOrders(\\n auctionId,\\n _minBuyAmount,\\n _sellAmount,\\n _prevSellOrder,\\n allowListCallData,\\n msg.sender\\n );\\n settleAuction(auctionId);\\n }\\n\\n // @dev function settling the auction and calculating the price\\n function settleAuction(uint256 auctionId)\\n public\\n atStageSolutionSubmission(auctionId)\\n returns (bytes32 clearingOrder)\\n {\\n (\\n uint64 auctioneerId,\\n uint96 minAuctionedBuyAmount,\\n uint96 fullAuctionedAmount\\n ) = auctionData[auctionId].initialAuctionOrder.decodeOrder();\\n\\n uint256 currentBidSum = auctionData[auctionId].interimSumBidAmount;\\n bytes32 currentOrder = auctionData[auctionId].interimOrder;\\n uint256 buyAmountOfIter;\\n uint256 sellAmountOfIter;\\n uint96 fillVolumeOfAuctioneerOrder = fullAuctionedAmount;\\n // Sum order up, until fullAuctionedAmount is fully bought or queue end is reached\\n do {\\n bytes32 nextOrder = sellOrders[auctionId].next(currentOrder);\\n if (nextOrder == IterableOrderedOrderSet.QUEUE_END) {\\n break;\\n }\\n currentOrder = nextOrder;\\n (, buyAmountOfIter, sellAmountOfIter) = currentOrder.decodeOrder();\\n currentBidSum = currentBidSum.add(sellAmountOfIter);\\n } while (\\n currentBidSum.mul(buyAmountOfIter) <\\n fullAuctionedAmount.mul(sellAmountOfIter)\\n );\\n\\n if (\\n currentBidSum > 0 &&\\n currentBidSum.mul(buyAmountOfIter) >=\\n fullAuctionedAmount.mul(sellAmountOfIter)\\n ) {\\n // All considered/summed orders are sufficient to close the auction fully\\n // at price between current and previous orders.\\n uint256 uncoveredBids =\\n currentBidSum.sub(\\n fullAuctionedAmount.mul(sellAmountOfIter).div(\\n buyAmountOfIter\\n )\\n );\\n\\n if (sellAmountOfIter >= uncoveredBids) {\\n //[13]\\n // Auction fully filled via partial match of currentOrder\\n uint256 sellAmountClearingOrder =\\n sellAmountOfIter.sub(uncoveredBids);\\n auctionData[auctionId]\\n .volumeClearingPriceOrder = sellAmountClearingOrder\\n .toUint96();\\n currentBidSum = currentBidSum.sub(uncoveredBids);\\n clearingOrder = currentOrder;\\n } else {\\n //[14]\\n // Auction fully filled via price strictly between currentOrder and the order\\n // immediately before. For a proof, see the security-considerations.md\\n currentBidSum = currentBidSum.sub(sellAmountOfIter);\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\n 0,\\n fullAuctionedAmount,\\n currentBidSum.toUint96()\\n );\\n }\\n } else {\\n // All considered/summed orders are not sufficient to close the auction fully at price of last order //[18]\\n // Either a higher price must be used or auction is only partially filled\\n\\n if (currentBidSum > minAuctionedBuyAmount) {\\n //[15]\\n // Price higher than last order would fill the auction\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\n 0,\\n fullAuctionedAmount,\\n currentBidSum.toUint96()\\n );\\n } else {\\n //[16]\\n // Even at the initial auction price, the auction is partially filled\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\n 0,\\n fullAuctionedAmount,\\n minAuctionedBuyAmount\\n );\\n fillVolumeOfAuctioneerOrder = currentBidSum\\n .mul(fullAuctionedAmount)\\n .div(minAuctionedBuyAmount)\\n .toUint96();\\n }\\n }\\n auctionData[auctionId].clearingPriceOrder = clearingOrder;\\n\\n if (auctionData[auctionId].minFundingThreshold > currentBidSum) {\\n auctionData[auctionId].minFundingThresholdNotReached = true;\\n }\\n processFeesAndAuctioneerFunds(\\n auctionId,\\n fillVolumeOfAuctioneerOrder,\\n auctioneerId,\\n fullAuctionedAmount\\n );\\n emit AuctionCleared(\\n auctionId,\\n fillVolumeOfAuctioneerOrder,\\n uint96(currentBidSum),\\n clearingOrder\\n );\\n // Gas refunds\\n auctionAccessManager[auctionId] = address(0);\\n delete auctionAccessData[auctionId];\\n auctionData[auctionId].initialAuctionOrder = bytes32(0);\\n auctionData[auctionId].interimOrder = bytes32(0);\\n auctionData[auctionId].interimSumBidAmount = uint256(0);\\n auctionData[auctionId].minimumBiddingAmountPerOrder = uint256(0);\\n }\\n\\n function claimFromParticipantOrder(\\n uint256 auctionId,\\n bytes32[] memory orders\\n )\\n public\\n atStageFinished(auctionId)\\n returns (\\n uint256 sumAuctioningTokenAmount,\\n uint256 sumBiddingTokenAmount\\n )\\n {\\n for (uint256 i = 0; i < orders.length; i++) {\\n // Note: we don't need to keep any information about the node since\\n // no new elements need to be inserted.\\n require(\\n sellOrders[auctionId].remove(orders[i]),\\n \\\"order is no longer claimable\\\"\\n );\\n }\\n AuctionData memory auction = auctionData[auctionId];\\n (, uint96 priceNumerator, uint96 priceDenominator) =\\n auction.clearingPriceOrder.decodeOrder();\\n (uint64 userId, , ) = orders[0].decodeOrder();\\n bool minFundingThresholdNotReached =\\n auctionData[auctionId].minFundingThresholdNotReached;\\n for (uint256 i = 0; i < orders.length; i++) {\\n (uint64 userIdOrder, uint96 buyAmount, uint96 sellAmount) =\\n orders[i].decodeOrder();\\n require(\\n userIdOrder == userId,\\n \\\"only allowed to claim for same user\\\"\\n );\\n if (minFundingThresholdNotReached) {\\n //[10]\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(sellAmount);\\n } else {\\n //[23]\\n if (orders[i] == auction.clearingPriceOrder) {\\n //[25]\\n sumAuctioningTokenAmount = sumAuctioningTokenAmount.add(\\n auction\\n .volumeClearingPriceOrder\\n .mul(priceNumerator)\\n .div(priceDenominator)\\n );\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(\\n sellAmount.sub(auction.volumeClearingPriceOrder)\\n );\\n } else {\\n if (orders[i].smallerThan(auction.clearingPriceOrder)) {\\n //[17]\\n sumAuctioningTokenAmount = sumAuctioningTokenAmount.add(\\n sellAmount.mul(priceNumerator).div(priceDenominator)\\n );\\n } else {\\n //[24]\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(\\n sellAmount\\n );\\n }\\n }\\n }\\n emit ClaimedFromOrder(auctionId, userId, buyAmount, sellAmount);\\n }\\n sendOutTokens(\\n auctionId,\\n sumAuctioningTokenAmount,\\n sumBiddingTokenAmount,\\n userId\\n ); //[3]\\n }\\n\\n function processFeesAndAuctioneerFunds(\\n uint256 auctionId,\\n uint256 fillVolumeOfAuctioneerOrder,\\n uint64 auctioneerId,\\n uint96 fullAuctionedAmount\\n ) internal {\\n uint256 feeAmount =\\n fullAuctionedAmount.mul(auctionData[auctionId].feeNumerator).div(\\n FEE_DENOMINATOR\\n ); //[20]\\n if (auctionData[auctionId].minFundingThresholdNotReached) {\\n sendOutTokens(\\n auctionId,\\n fullAuctionedAmount.add(feeAmount),\\n 0,\\n auctioneerId\\n ); //[4]\\n } else {\\n //[11]\\n (, uint96 priceNumerator, uint96 priceDenominator) =\\n auctionData[auctionId].clearingPriceOrder.decodeOrder();\\n uint256 unsettledAuctionTokens =\\n fullAuctionedAmount.sub(fillVolumeOfAuctioneerOrder);\\n uint256 auctioningTokenAmount =\\n unsettledAuctionTokens.add(\\n feeAmount.mul(unsettledAuctionTokens).div(\\n fullAuctionedAmount\\n )\\n );\\n uint256 biddingTokenAmount =\\n fillVolumeOfAuctioneerOrder.mul(priceDenominator).div(\\n priceNumerator\\n );\\n sendOutTokens(\\n auctionId,\\n auctioningTokenAmount,\\n biddingTokenAmount,\\n auctioneerId\\n ); //[5]\\n sendOutTokens(\\n auctionId,\\n feeAmount.mul(fillVolumeOfAuctioneerOrder).div(\\n fullAuctionedAmount\\n ),\\n 0,\\n feeReceiverUserId\\n ); //[7]\\n }\\n }\\n\\n function sendOutTokens(\\n uint256 auctionId,\\n uint256 auctioningTokenAmount,\\n uint256 biddingTokenAmount,\\n uint64 userId\\n ) internal {\\n address userAddress = registeredUsers.getAddressAt(userId);\\n if (auctioningTokenAmount > 0) {\\n auctionData[auctionId].auctioningToken.safeTransfer(\\n userAddress,\\n auctioningTokenAmount\\n );\\n }\\n if (biddingTokenAmount > 0) {\\n auctionData[auctionId].biddingToken.safeTransfer(\\n userAddress,\\n biddingTokenAmount\\n );\\n }\\n }\\n\\n function registerUser(address user) public returns (uint64 userId) {\\n numUsers = numUsers.add(1).toUint64();\\n require(\\n registeredUsers.insert(numUsers, user),\\n \\\"User already registered\\\"\\n );\\n userId = numUsers;\\n emit UserRegistration(user, userId);\\n }\\n\\n function getUserId(address user) public returns (uint64 userId) {\\n if (registeredUsers.hasAddress(user)) {\\n userId = registeredUsers.getId(user);\\n } else {\\n userId = registerUser(user);\\n emit NewUser(userId, user);\\n }\\n }\\n\\n function getSecondsRemainingInBatch(uint256 auctionId)\\n public\\n view\\n returns (uint256)\\n {\\n if (auctionData[auctionId].auctionEndDate < block.timestamp) {\\n return 0;\\n }\\n return auctionData[auctionId].auctionEndDate.sub(block.timestamp);\\n }\\n\\n function containsOrder(uint256 auctionId, bytes32 order)\\n public\\n view\\n returns (bool)\\n {\\n return sellOrders[auctionId].contains(order);\\n }\\n}\\n\",\"keccak256\":\"0x4fbbc969d2b2de6d6b9dbb99e16cbf7cdb2dfc0f2b20cac4cbb129a700ab9b69\"},\"contracts/interfaces/AllowListVerifier.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-or-later\\npragma solidity >=0.6.8;\\n\\nlibrary AllowListVerifierHelper {\\n /// @dev Value returned by a call to `isAllowed` if the check\\n /// was successful. The value is defined as:\\n /// bytes4(keccak256(\\\"isAllowed(address,uint256,bytes)\\\"))\\n bytes4 internal constant MAGICVALUE = 0x19a05a7e;\\n}\\n\\n///\\n/// @dev Standardized interface for an allowList manager for easyAuction\\n/// The interface was inspired by EIP-1271\\ninterface AllowListVerifier {\\n /// @dev Should return whether the a specific user has access to an auction\\n /// by returning the magic value from AllowListVerifierHelper\\n function isAllowed(\\n address user,\\n uint256 auctionId,\\n bytes calldata callData\\n ) external view returns (bytes4);\\n}\\n\",\"keccak256\":\"0xbd0978c0fbf4e06e609615535face4d03bc156d890c916cea4dcb2d493ca1487\",\"license\":\"LGPL-3.0-or-later\"},\"contracts/libraries/IdToAddressBiMap.sol\":{\"content\":\"pragma solidity ^0.6.0;\\n\\n///////////////////////////////////////////////////////////////////////////////////////////////////////////\\n// Contract does not have test coverage, as it was nearly copied from:\\n// https://github.com/gnosis/solidity-data-structures/blob/master/contracts/libraries/IdToAddressBiMap.sol\\n// The only change is uint16 -> uint64\\n///////////////////////////////////////////////////////////////////////////////////////////////////////////\\n\\nlibrary IdToAddressBiMap {\\n struct Data {\\n mapping(uint64 => address) idToAddress;\\n mapping(address => uint64) addressToId;\\n }\\n\\n function hasId(Data storage self, uint64 id) internal view returns (bool) {\\n return self.idToAddress[id + 1] != address(0);\\n }\\n\\n function hasAddress(Data storage self, address addr)\\n internal\\n view\\n returns (bool)\\n {\\n return self.addressToId[addr] != 0;\\n }\\n\\n function getAddressAt(Data storage self, uint64 id)\\n internal\\n view\\n returns (address)\\n {\\n require(hasId(self, id), \\\"Must have ID to get Address\\\");\\n return self.idToAddress[id + 1];\\n }\\n\\n function getId(Data storage self, address addr)\\n internal\\n view\\n returns (uint64)\\n {\\n require(hasAddress(self, addr), \\\"Must have Address to get ID\\\");\\n return self.addressToId[addr] - 1;\\n }\\n\\n function insert(\\n Data storage self,\\n uint64 id,\\n address addr\\n ) internal returns (bool) {\\n require(addr != address(0), \\\"Cannot insert zero address\\\");\\n require(id != uint64(-1), \\\"Cannot insert max uint64\\\");\\n // Ensure bijectivity of the mappings\\n if (\\n self.addressToId[addr] != 0 ||\\n self.idToAddress[id + 1] != address(0)\\n ) {\\n return false;\\n }\\n self.idToAddress[id + 1] = addr;\\n self.addressToId[addr] = id + 1;\\n return true;\\n }\\n}\\n\",\"keccak256\":\"0x93efb312cc8c4956c462453559c8c0e1c090a0ac1f454d2ac9055fb7e4e3129d\"},\"contracts/libraries/IterableOrderedOrderSet.sol\":{\"content\":\"pragma solidity >=0.6.8;\\n\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\n\\nlibrary IterableOrderedOrderSet {\\n using SafeMath for uint96;\\n using IterableOrderedOrderSet for bytes32;\\n\\n // represents smallest possible value for an order under comparison of fn smallerThan()\\n bytes32 internal constant QUEUE_START =\\n 0x0000000000000000000000000000000000000000000000000000000000000001;\\n // represents highest possible value for an order under comparison of fn smallerThan()\\n bytes32 internal constant QUEUE_END =\\n 0xffffffffffffffffffffffffffffffffffffffff000000000000000000000001;\\n\\n /// The struct is used to implement a modified version of a doubly linked\\n /// list with sorted elements. The list starts from QUEUE_START to\\n /// QUEUE_END, and each node keeps track of its predecessor and successor.\\n /// Nodes can be added or removed.\\n ///\\n /// `next` and `prev` have a different role. The list is supposed to be\\n /// traversed with `next`. If `next` is empty, the node is not part of the\\n /// list. However, `prev` might be set for elements that are not in the\\n /// list, which is why it should not be used for traversing. Having a `prev`\\n /// set for elements not in the list is used to keep track of the history of\\n /// the position in the list of a removed element.\\n struct Data {\\n mapping(bytes32 => bytes32) nextMap;\\n mapping(bytes32 => bytes32) prevMap;\\n }\\n\\n struct Order {\\n uint64 owner;\\n uint96 buyAmount;\\n uint96 sellAmount;\\n }\\n\\n function initializeEmptyList(Data storage self) internal {\\n self.nextMap[QUEUE_START] = QUEUE_END;\\n self.prevMap[QUEUE_END] = QUEUE_START;\\n }\\n\\n function isEmpty(Data storage self) internal view returns (bool) {\\n return self.nextMap[QUEUE_START] == QUEUE_END;\\n }\\n\\n function insert(\\n Data storage self,\\n bytes32 elementToInsert,\\n bytes32 elementBeforeNewOne\\n ) internal returns (bool) {\\n (, , uint96 denominator) = decodeOrder(elementToInsert);\\n require(denominator != uint96(0), \\\"Inserting zero is not supported\\\");\\n require(\\n elementToInsert != QUEUE_START && elementToInsert != QUEUE_END,\\n \\\"Inserting element is not valid\\\"\\n );\\n if (contains(self, elementToInsert)) {\\n return false;\\n }\\n if (\\n elementBeforeNewOne != QUEUE_START &&\\n self.prevMap[elementBeforeNewOne] == bytes32(0)\\n ) {\\n return false;\\n }\\n if (!elementBeforeNewOne.smallerThan(elementToInsert)) {\\n return false;\\n }\\n\\n // `elementBeforeNewOne` might have been removed during the time it\\n // took to the transaction calling this function to be mined, so\\n // the new order cannot be appended directly to this. We follow the\\n // history of previous links backwards until we find an element in\\n // the list from which to start our search.\\n // Note that following the link backwards returns elements that are\\n // before `elementBeforeNewOne` in sorted order.\\n while (self.nextMap[elementBeforeNewOne] == bytes32(0)) {\\n elementBeforeNewOne = self.prevMap[elementBeforeNewOne];\\n }\\n\\n // `elementBeforeNewOne` belongs now to the linked list. We search the\\n // largest entry that is smaller than the element to insert.\\n bytes32 previous;\\n bytes32 current = elementBeforeNewOne;\\n do {\\n previous = current;\\n current = self.nextMap[current];\\n } while (current.smallerThan(elementToInsert));\\n // Note: previous < elementToInsert < current\\n self.nextMap[previous] = elementToInsert;\\n self.prevMap[current] = elementToInsert;\\n self.prevMap[elementToInsert] = previous;\\n self.nextMap[elementToInsert] = current;\\n\\n return true;\\n }\\n\\n /// The element is removed from the linked list, but the node retains\\n /// information on which predecessor it had, so that a node in the chain\\n /// can be reached by following the predecessor chain of deleted elements.\\n function removeKeepHistory(Data storage self, bytes32 elementToRemove)\\n internal\\n returns (bool)\\n {\\n if (!contains(self, elementToRemove)) {\\n return false;\\n }\\n bytes32 previousElement = self.prevMap[elementToRemove];\\n bytes32 nextElement = self.nextMap[elementToRemove];\\n self.nextMap[previousElement] = nextElement;\\n self.prevMap[nextElement] = previousElement;\\n self.nextMap[elementToRemove] = bytes32(0);\\n return true;\\n }\\n\\n /// Remove an element from the chain, clearing all related storage.\\n /// Note that no elements should be inserted using as a reference point a\\n /// node deleted after calling `remove`, since an element in the `prev`\\n /// chain might be missing.\\n function remove(Data storage self, bytes32 elementToRemove)\\n internal\\n returns (bool)\\n {\\n bool result = removeKeepHistory(self, elementToRemove);\\n if (result) {\\n self.prevMap[elementToRemove] = bytes32(0);\\n }\\n return result;\\n }\\n\\n function contains(Data storage self, bytes32 value)\\n internal\\n view\\n returns (bool)\\n {\\n if (value == QUEUE_START) {\\n return false;\\n }\\n // Note: QUEUE_END is not contained in the list since it has no\\n // successor.\\n return self.nextMap[value] != bytes32(0);\\n }\\n\\n // @dev orders are ordered by\\n // 1. their price - buyAmount/sellAmount\\n // 2. by the sellAmount\\n // 3. their userId,\\n function smallerThan(bytes32 orderLeft, bytes32 orderRight)\\n internal\\n pure\\n returns (bool)\\n {\\n (\\n uint64 userIdLeft,\\n uint96 priceNumeratorLeft,\\n uint96 priceDenominatorLeft\\n ) = decodeOrder(orderLeft);\\n (\\n uint64 userIdRight,\\n uint96 priceNumeratorRight,\\n uint96 priceDenominatorRight\\n ) = decodeOrder(orderRight);\\n\\n if (\\n priceNumeratorLeft.mul(priceDenominatorRight) <\\n priceNumeratorRight.mul(priceDenominatorLeft)\\n ) return true;\\n if (\\n priceNumeratorLeft.mul(priceDenominatorRight) >\\n priceNumeratorRight.mul(priceDenominatorLeft)\\n ) return false;\\n\\n if (priceNumeratorLeft < priceNumeratorRight) return true;\\n if (priceNumeratorLeft > priceNumeratorRight) return false;\\n require(\\n userIdLeft != userIdRight,\\n \\\"user is not allowed to place same order twice\\\"\\n );\\n if (userIdLeft < userIdRight) {\\n return true;\\n }\\n return false;\\n }\\n\\n function first(Data storage self) internal view returns (bytes32) {\\n require(!isEmpty(self), \\\"Trying to get first from empty set\\\");\\n return self.nextMap[QUEUE_START];\\n }\\n\\n function next(Data storage self, bytes32 value)\\n internal\\n view\\n returns (bytes32)\\n {\\n require(value != QUEUE_END, \\\"Trying to get next of last element\\\");\\n bytes32 nextElement = self.nextMap[value];\\n require(\\n nextElement != bytes32(0),\\n \\\"Trying to get next of non-existent element\\\"\\n );\\n return nextElement;\\n }\\n\\n function decodeOrder(bytes32 _orderData)\\n internal\\n pure\\n returns (\\n uint64 userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n )\\n {\\n // Note: converting to uint discards the binary digits that do not fit\\n // the type.\\n userId = uint64(uint256(_orderData) >> 192);\\n buyAmount = uint96(uint256(_orderData) >> 96);\\n sellAmount = uint96(uint256(_orderData));\\n }\\n\\n function encodeOrder(\\n uint64 userId,\\n uint96 buyAmount,\\n uint96 sellAmount\\n ) internal pure returns (bytes32) {\\n return\\n bytes32(\\n (uint256(userId) << 192) +\\n (uint256(buyAmount) << 96) +\\n uint256(sellAmount)\\n );\\n }\\n}\\n\",\"keccak256\":\"0xdcc090564f29439c38f4eb85115ba9ba4479a7494cd9e877fdc2b6d19b94d574\"},\"contracts/libraries/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity >=0.6.0 <0.8.0;\\n\\n/**\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\n * checks.\\n *\\n * Logic was copied and modified from here: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/SafeCast.sol\\n */\\nlibrary SafeCast {\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value < 2**96, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(value);\\n }\\n\\n function toUint64(uint256 value) internal pure returns (uint64) {\\n require(value < 2**64, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\n return uint64(value);\\n }\\n}\\n\",\"keccak256\":\"0x9f12a3c511cd8ea260bc8faa7d2e4d59a823328ef07c26af506385aa3e92b200\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405260006009556001600a60006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055503480156200004057600080fd5b50600062000053620000f760201b60201c565b9050806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620000ff565b600033905090565b615b6e806200010f6000396000f3fe608060405234801561001057600080fd5b50600436106101585760003560e01c80637882deaf116100c3578063d73792a91161007c578063d73792a914610ccf578063e4a59ef414610ced578063e86dea4a14610d45578063ec20d0bb14610d63578063f2fde38b14610fe0578063f59c2f061461102457610158565b80637882deaf146106425780637ed18b701461071f5780638da5cb5b146107e157806391cfc1d414610815578063a7e7664414610a54578063d225269c14610a7257610158565b80633e12905f116101155780633e12905f1461046157806340b20b091461049957806355fc62d2146104e75780635cefb291146105c257806363c699a4146105ea578063715018a61461063857610158565b80630a4cd6c91461015d57806315d37b4b146102f157806319a50f49146103335780632199d5cd1461035b5780632b956ff7146103bd5780632e9936111461041f575b600080fd5b6102db600480360361016081101561017457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080356bffffffffffffffffffffffff16906020019092919080356bffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803515159060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561025557600080fd5b82018360208201111561026757600080fd5b8035906020019184600183028401116401000000008311171561028957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506110cb565b6040518082815260200191505060405180910390f35b61031d6004803603602081101561030757600080fd5b810190808035906020019092919050505061178a565b6040518082815260200191505060405180910390f35b61033b6117e4565b604051808267ffffffffffffffff16815260200191505060405180910390f35b61039d6004803603602081101561037157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506117fe565b604051808267ffffffffffffffff16815260200191505060405180910390f35b6103ff600480360360208110156103d357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611978565b604051808267ffffffffffffffff16815260200191505060405180910390f35b61044b6004803603602081101561043557600080fd5b8101908080359060200190929190505050611a0d565b6040518082815260200191505060405180910390f35b6104976004803603604081101561047757600080fd5b810190808035906020019092919080359060200190929190505050611fb4565b005b6104e5600480360360408110156104af57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122d6565b005b610513600480360360208110156104fd57600080fd5b8101908080359060200190929190505050612434565b604051808f73ffffffffffffffffffffffffffffffffffffffff1681526020018e73ffffffffffffffffffffffffffffffffffffffff1681526020018d81526020018c81526020018b81526020018a8152602001898152602001888152602001878152602001866bffffffffffffffffffffffff168152602001851515815260200184151581526020018381526020018281526020019e50505050505050505050505050505060405180910390f35b6105ca612512565b604051808267ffffffffffffffff16815260200191505060405180910390f35b6106206004803603604081101561060057600080fd5b81019080803590602001909291908035906020019092919050505061252c565b60405180821515815260200191505060405180910390f35b61064061255b565b005b6107026004803603604081101561065857600080fd5b81019080803590602001909291908035906020019064010000000081111561067f57600080fd5b82018360208201111561069157600080fd5b803590602001918460208302840111640100000000831117156106b357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192905050506126e1565b604051808381526020018281526020019250505060405180910390f35b6107df6004803603604081101561073557600080fd5b81019080803590602001909291908035906020019064010000000081111561075c57600080fd5b82018360208201111561076e57600080fd5b8035906020019184602083028401116401000000008311171561079057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050612d2d565b005b6107e9612f90565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610a52600480360360a081101561082b57600080fd5b81019080803590602001909291908035906020019064010000000081111561085257600080fd5b82018360208201111561086457600080fd5b8035906020019184602083028401116401000000008311171561088657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156108e657600080fd5b8201836020820111156108f857600080fd5b8035906020019184602083028401116401000000008311171561091a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561097a57600080fd5b82018360208201111561098c57600080fd5b803590602001918460208302840111640100000000831117156109ae57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610a0e57600080fd5b820183602082011115610a2057600080fd5b80359060200191846001830284011164010000000083111715610a4257600080fd5b9091929391929390505050612fb9565b005b610a5c613221565b6040518082815260200191505060405180910390f35b610caf600480360360a0811015610a8857600080fd5b810190808035906020019092919080359060200190640100000000811115610aaf57600080fd5b820183602082011115610ac157600080fd5b80359060200191846020830284011164010000000083111715610ae357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610b4357600080fd5b820183602082011115610b5557600080fd5b80359060200191846020830284011164010000000083111715610b7757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610bd757600080fd5b820183602082011115610be957600080fd5b80359060200191846020830284011164010000000083111715610c0b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610c6b57600080fd5b820183602082011115610c7d57600080fd5b80359060200191846001830284011164010000000083111715610c9f57600080fd5b9091929391929390505050613227565b604051808267ffffffffffffffff16815260200191505060405180910390f35b610cd76132b4565b6040518082815260200191505060405180910390f35b610d1960048036036020811015610d0357600080fd5b81019080803590602001909291905050506132ba565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610d4d6132ed565b6040518082815260200191505060405180910390f35b610fc0600480360360c0811015610d7957600080fd5b810190808035906020019092919080359060200190640100000000811115610da057600080fd5b820183602082011115610db257600080fd5b80359060200191846020830284011164010000000083111715610dd457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610e3457600080fd5b820183602082011115610e4657600080fd5b80359060200191846020830284011164010000000083111715610e6857600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ec857600080fd5b820183602082011115610eda57600080fd5b80359060200191846020830284011164010000000083111715610efc57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610f5c57600080fd5b820183602082011115610f6e57600080fd5b80359060200191846001830284011164010000000083111715610f9057600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506132f3565b604051808267ffffffffffffffff16815260200191505060405180910390f35b61102260048036036020811015610ff657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613381565b005b6110506004803603602081101561103a57600080fd5b810190808035906020019092919050505061358c565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611090578082015181840152602081019050611075565b50505050905090810190601f1680156110bd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000611144333061111d6103e861110f6110f26009546103e861363c90919063ffffffff16565b8e6bffffffffffffffffffffffff166136c490919063ffffffff16565b61374a90919063ffffffff16565b8f73ffffffffffffffffffffffffffffffffffffffff16613794909392919063ffffffff16565b6000886bffffffffffffffffffffffff16116111c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f63616e6e6f742061756374696f6e207a65726f20746f6b656e7300000000000081525060200191505060405180910390fd5b6000876bffffffffffffffffffffffff161161122f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806158406023913960400191505060405180910390fd5b60008611611288576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806159a66036913960400191505060405180910390fd5b888a11156112e1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180615ac46029913960400191505060405180910390fd5b428911611339576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061592f6026913960400191505060405180910390fd5b61134f600160085461363c90919063ffffffff16565b600881905550611372600160006008548152602001908152602001600020613855565b600061137d33611978565b9050604051806101c001604052808e73ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff1681526020018c81526020018b81526020016113da838b8d6138da565b815260200188815260200160008152602001600160001b81526020016000801b815260200160006bffffffffffffffffffffffff168152602001600015158152602001861515815260200160095481526020018781525060026000600854815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e0820151816007015561010082015181600801556101208201518160090160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061014082015181600901600c6101000a81548160ff02191690831515021790555061016082015181600901600d6101000a81548160ff02191690831515021790555061018082015181600a01556101a082015181600b01559050508360036000600854815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600460006008548152602001908152602001600020908051906020019061162b9291906155dc565b508b73ffffffffffffffffffffffffffffffffffffffff168d73ffffffffffffffffffffffffffffffffffffffff166008547f728d0fed13687f1840de94f5ae640eae49b43eda26b7ffe97e55e79a0de6e40c8e8e868f8f8f8f8e8e604051808a81526020018981526020018867ffffffffffffffff168152602001876bffffffffffffffffffffffff168152602001866bffffffffffffffffffffffff1681526020018581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611733578082015181840152602081019050611718565b50505050905090810190601f1680156117605780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390a46008549150509b9a5050505050505050505050565b600042600260008481526020019081526020016000206003015410156117b357600090506117df565b6117dc42600260008581526020019081526020016000206003015461391b90919063ffffffff16565b90505b919050565b600760009054906101000a900467ffffffffffffffff1681565b600061183c6118376001600760009054906101000a900467ffffffffffffffff1667ffffffffffffffff1661363c90919063ffffffff16565b613965565b600760006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550611890600760009054906101000a900467ffffffffffffffff168360056139d09092919063ffffffff16565b611902576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f5573657220616c7265616479207265676973746572656400000000000000000081525060200191505060405180910390fd5b600760009054906101000a900467ffffffffffffffff1690508173ffffffffffffffffffffffffffffffffffffffff167f6838f67cb358c332087b73dbe769a6c869a5f87225236c16dda5d0013a77074c82604051808267ffffffffffffffff16815260200191505060405180910390a2919050565b600061198e826005613cf690919063ffffffff16565b156119ae576119a7826005613d6390919063ffffffff16565b9050611a08565b6119b7826117fe565b90508173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f969d438b19b6b5fb3c0d3c6f16867e519fcec4233799d6be29d1c00f2045ba2660405160405180910390a35b919050565b60008160006002600083815260200190815260200160002060030154905060008114158015611a3c5750804210155b8015611a6057506000801b6002600084815260200190815260200160002060080154145b611ab5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615a466028913960400191505060405180910390fd5b506000806000611ada6002600088815260200190815260200160002060040154613e42565b92509250925060006002600088815260200190815260200160002060060154905060006002600089815260200190815260200160002060070154905060008060008590505b6000611b4685600160008f8152602001908152602001600020613e6890919063ffffffff16565b90507fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b811415611b795750611c02565b809450611b8585613e42565b909150816bffffffffffffffffffffffff169150806bffffffffffffffffffffffff1690508094508195505050611bc5838761363c90919063ffffffff16565b955050611be982876bffffffffffffffffffffffff166136c490919063ffffffff16565b611bfc84876136c490919063ffffffff16565b10611b1f575b600085118015611c445750611c2e82876bffffffffffffffffffffffff166136c490919063ffffffff16565b611c4184876136c490919063ffffffff16565b10155b15611d4d576000611c90611c8185611c73868b6bffffffffffffffffffffffff166136c490919063ffffffff16565b61374a90919063ffffffff16565b8761391b90919063ffffffff16565b9050808310611d1b576000611cae828561391b90919063ffffffff16565b9050611cb981613f66565b600260008f815260200190815260200160002060090160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611d10828861391b90919063ffffffff16565b9650859b5050611d47565b611d2e838761391b90919063ffffffff16565b9550611d44600088611d3f89613f66565b6138da565b9a505b50611dd9565b866bffffffffffffffffffffffff16851115611d7e57611d77600087611d7288613f66565b6138da565b9950611dd8565b611d8a600087896138da565b9950611dd5611dd0886bffffffffffffffffffffffff16611dc2896bffffffffffffffffffffffff16896136c490919063ffffffff16565b61374a90919063ffffffff16565b613f66565b90505b5b89600260008d81526020019081526020016000206008018190555084600260008d8152602001908152602001600020600b01541115611e42576001600260008d8152602001908152602001600020600901600c6101000a81548160ff0219169083151502179055505b611e5c8b826bffffffffffffffffffffffff168a89613fd5565b8a7f4d160a2a345f2faeb9ac2e65272820b8ca5473b80aabef416bdf7e07ee7f591082878d60405180846bffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001828152602001935050505060405180910390a26000600360008d815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600460008c81526020019081526020016000206000611f32919061565c565b6000801b600260008d8152602001908152602001600020600401819055506000801b600260008d8152602001908152602001600020600701819055506000600260008d8152602001908152602001600020600601819055506000600260008d815260200190815260200160002060050181905550505050505050505050919050565b8160006002600083815260200190815260200160002060030154905060008114158015611fe15750804210155b801561200557506000801b6002600084815260200190815260200160002060080154145b61205a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615a466028913960400191505060405180910390fd5b50600061207c6002600086815260200190815260200160002060040154613e42565b9250505060006002600086815260200190815260200160002060060154905060006002600087815260200190815260200160002060070154905060005b85811015612128576120e682600160008a8152602001908152602001600020613e6890919063ffffffff16565b915060006120f383613e42565b92505050612118816bffffffffffffffffffffffff168561363c90919063ffffffff16565b93505080806001019150506120b9565b507fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b8114156121c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f7265616368656420656e64206f66206f72646572206c6973740000000000000081525060200191505060405180910390fd5b6000806121ce83613e42565b9250925050612202816bffffffffffffffffffffffff16866bffffffffffffffffffffffff166136c490919063ffffffff16565b612223836bffffffffffffffffffffffff16866136c490919063ffffffff16565b10612296576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f746f6f206d616e79206f72646572732073756d6d65642075700000000000000081525060200191505060405180910390fd5b83600260008a81526020019081526020016000206006018190555082600260008a8152602001908152602001600020600701819055505050505050505050565b6122de6141c7565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461239e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600f8211156123f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180615902602d913960400191505060405180910390fd5b61240181611978565b600a60006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816009819055505050565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154908060060154908060070154908060080154908060090160009054906101000a90046bffffffffffffffffffffffff169080600901600c9054906101000a900460ff169080600901600d9054906101000a900460ff169080600a01549080600b015490508e565b600a60009054906101000a900467ffffffffffffffff1681565b600061255382600160008681526020019081526020016000206141cf90919063ffffffff16565b905092915050565b6125636141c7565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612623576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600080836000801b60026000838152602001908152602001600020600801541415612774576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f41756374696f6e206e6f74207965742066696e6973686564000000000000000081525060200191505060405180910390fd5b60005b8451811015612837576127b885828151811061278f57fe5b60200260200101516001600089815260200190815260200160002061420b90919063ffffffff16565b61282a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f6f72646572206973206e6f206c6f6e67657220636c61696d61626c650000000081525060200191505060405180910390fd5b8080600101915050612777565b506128406156a4565b60026000878152602001908152602001600020604051806101c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160098201600c9054906101000a900460ff1615151515815260200160098201600d9054906101000a900460ff16151515158152602001600a8201548152602001600b8201548152505090506000806129ec836101000151613e42565b92509250506000612a1088600081518110612a0357fe5b6020026020010151613e42565b505090506000600260008b8152602001908152602001600020600901600c9054906101000a900460ff16905060005b8951811015612d13576000806000612a698d8581518110612a5c57fe5b6020026020010151613e42565b9250925092508567ffffffffffffffff168367ffffffffffffffff1614612adb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615a236023913960400191505060405180910390fd5b8415612b0957612b02816bffffffffffffffffffffffff168c61363c90919063ffffffff16565b9a50612c9c565b8861010001518d8581518110612b1b57fe5b60200260200101511415612bde57612b8f612b80886bffffffffffffffffffffffff16612b728b6bffffffffffffffffffffffff168d61012001516bffffffffffffffffffffffff166136c490919063ffffffff16565b61374a90919063ffffffff16565b8d61363c90919063ffffffff16565b9b50612bd7612bc88a61012001516bffffffffffffffffffffffff16836bffffffffffffffffffffffff1661391b90919063ffffffff16565b8c61363c90919063ffffffff16565b9a50612c9b565b612c098961010001518e8681518110612bf357fe5b602002602001015161424890919063ffffffff16565b15612c7657612c6f612c60886bffffffffffffffffffffffff16612c528b6bffffffffffffffffffffffff16856bffffffffffffffffffffffff166136c490919063ffffffff16565b61374a90919063ffffffff16565b8d61363c90919063ffffffff16565b9b50612c9a565b612c97816bffffffffffffffffffffffff168c61363c90919063ffffffff16565b9a505b5b5b8567ffffffffffffffff168e7f3f2c83616e48a2f8b3c9cc26499e2e5c61643714dac49027d82cf6732f96a91a848460405180836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681526020019250505060405180910390a35050508080600101915050612a3f565b50612d208a898985614466565b5050505050509250929050565b8160026000828152602001908152602001600020600201544210612d9c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806158636032913960400191505060405180910390fd5b6000612da733611978565b90506000805b8451811015612f27576000612df0868381518110612dc757fe5b6020026020010151600160008a815260200190815260200160002061455b90919063ffffffff16565b90508015612f19576000806000612e19898681518110612e0c57fe5b6020026020010151613e42565b9250925092508667ffffffffffffffff168367ffffffffffffffff1614612e8b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806157f76023913960400191505060405180910390fd5b612eac816bffffffffffffffffffffffff168761363c90919063ffffffff16565b95508667ffffffffffffffff168a7f7edae327fe79804b2f38bd490d874a0d188d3ae8911b303205abe47400086ac4848460405180836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681526020019250505060405180910390a35050505b508080600101915050612dad565b50612f8933826002600089815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166146069092919063ffffffff16565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b8560006002600083815260200190815260200160002060030154905060008114158015612fe65750804210155b801561300a57506000801b6002600084815260200190815260200160002060080154145b61305f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615a466028913960400191505060405180910390fd5b5060026000888152602001908152602001600020600901600d9054906101000a900460ff166130d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061579e6028913960400191505060405180910390fd5b600186511480156130eb575060018551145b613140576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806159556027913960400191505060405180910390fd5b600061314b33611978565b90506131a8613183828960008151811061316157fe5b60200260200101518960008151811061317657fe5b60200260200101516138da565b600260008b81526020019081526020016000206007015461424890919063ffffffff16565b6131fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806157c66031913960400191505060405180910390fd5b61320c888888888888336146a8565b5061321688611a0d565b505050505050505050565b60085481565b60008660026000828152602001908152602001600020600301544210613298576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615b176022913960400191505060405180910390fd5b6132a7888888888888336146a8565b9150509695505050505050565b6103e881565b60036020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60095481565b60008760026000828152602001908152602001600020600301544210613364576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615b176022913960400191505060405180910390fd5b613373898989898989896146a8565b915050979650505050505050565b6133896141c7565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613449576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156134cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061581a6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156136345780601f1061360957610100808354040283529160200191613634565b820191906000526020600020905b81548152906001019060200180831161361757829003601f168201915b505050505081565b6000808284019050838110156136ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000808314156136d75760009050613744565b60008284029050828482816136e857fe5b041461373f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806159dc6021913960400191505060405180910390fd5b809150505b92915050565b600061378c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614cc0565b905092915050565b61384f846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614d86565b50505050565b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b816000016000600160001b815260200190815260200160002081905550600160001b8160010160007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b81526020019081526020016000208190555050565b6000816bffffffffffffffffffffffff166060846bffffffffffffffffffffffff16901b60c08667ffffffffffffffff16901b010160001b90509392505050565b600061395d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614e75565b905092915050565b60006801000000000000000082106139c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806159fd6026913960400191505060405180910390fd5b819050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613a74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f43616e6e6f7420696e73657274207a65726f206164647265737300000000000081525060200191505060405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff67ffffffffffffffff168367ffffffffffffffff161415613b1e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f43616e6e6f7420696e73657274206d61782075696e743634000000000000000081525060200191505060405180910390fd5b60008460010160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900467ffffffffffffffff1667ffffffffffffffff16141580613c065750600073ffffffffffffffffffffffffffffffffffffffff168460000160006001860167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b15613c145760009050613cef565b818460000160006001860167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600183018460010160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600190505b9392505050565b6000808360010160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900467ffffffffffffffff1667ffffffffffffffff161415905092915050565b6000613d6f8383613cf6565b613de1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4d7573742068617665204164647265737320746f20676574204944000000000081525060200191505060405180910390fd5b60018360010160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900467ffffffffffffffff1603905092915050565b600080600060c08460001c901c925060608460001c901c91508360001c90509193909250565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b821415613ee6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806158ba6022913960400191505060405180910390fd5b60008360000160008481526020019081526020016000205490506000801b811415613f5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061597c602a913960400191505060405180910390fd5b8091505092915050565b60006c010000000000000000000000008210613fcd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806157786026913960400191505060405180910390fd5b819050919050565b60006140226103e861401460026000898152602001908152602001600020600a0154856bffffffffffffffffffffffff166136c490919063ffffffff16565b61374a90919063ffffffff16565b905060026000868152602001908152602001600020600901600c9054906101000a900460ff161561407f5761407a8561407283856bffffffffffffffffffffffff1661363c90919063ffffffff16565b600086614466565b6141c0565b6000806140a16002600089815260200190815260200160002060080154613e42565b925092505060006140c987866bffffffffffffffffffffffff1661391b90919063ffffffff16565b90506000614112614103876bffffffffffffffffffffffff166140f585896136c490919063ffffffff16565b61374a90919063ffffffff16565b8361363c90919063ffffffff16565b90506000614157856bffffffffffffffffffffffff16614149866bffffffffffffffffffffffff168c6136c490919063ffffffff16565b61374a90919063ffffffff16565b90506141658a83838b614466565b6141ba8a61419c896bffffffffffffffffffffffff1661418e8d8b6136c490919063ffffffff16565b61374a90919063ffffffff16565b6000600a60009054906101000a900467ffffffffffffffff16614466565b50505050505b5050505050565b600033905090565b6000600160001b8214156141e65760009050614205565b6000801b83600001600084815260200190815260200160002054141590505b92915050565b600080614218848461455b565b9050801561423e576000801b846001016000858152602001908152602001600020819055505b8091505092915050565b60008060008061425786613e42565b925092509250600080600061426b88613e42565b9250925092506142a0846bffffffffffffffffffffffff16836bffffffffffffffffffffffff166136c490919063ffffffff16565b6142cf826bffffffffffffffffffffffff16876bffffffffffffffffffffffff166136c490919063ffffffff16565b10156142e45760019650505050505050614460565b614313846bffffffffffffffffffffffff16836bffffffffffffffffffffffff166136c490919063ffffffff16565b614342826bffffffffffffffffffffffff16876bffffffffffffffffffffffff166136c490919063ffffffff16565b11156143575760009650505050505050614460565b816bffffffffffffffffffffffff16856bffffffffffffffffffffffff16101561438a5760019650505050505050614460565b816bffffffffffffffffffffffff16856bffffffffffffffffffffffff1611156143bd5760009650505050505050614460565b8267ffffffffffffffff168667ffffffffffffffff16141561442a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180615a6e602d913960400191505060405180910390fd5b8267ffffffffffffffff168667ffffffffffffffff1610156144555760019650505050505050614460565b600096505050505050505b92915050565b600061447c826005614f3590919063ffffffff16565b905060008411156144e9576144e881856002600089815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166146069092919063ffffffff16565b5b60008311156145545761455381846002600089815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166146069092919063ffffffff16565b5b5050505050565b600061456783836141cf565b6145745760009050614600565b60008360010160008481526020019081526020016000205490506000846000016000858152602001908152602001600020549050808560000160008481526020019081526020016000208190555081856001016000838152602001908152602001600020819055506000801b856000016000868152602001908152602001600020819055506001925050505b92915050565b6146a38363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614d86565b505050565b600080600360008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146148ad576319a05a7e60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168173ffffffffffffffffffffffffffffffffffffffff166319a05a7e858c89896040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060206040518083038186803b1580156147df57600080fd5b505afa1580156147f3573d6000803e3d6000fd5b505050506040513d602081101561480957600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146148ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f75736572206e6f7420616c6c6f77656420746f20706c616365206f726465720081525060200191505060405180910390fd5b5b506000806148d0600260008c815260200190815260200160002060040154613e42565b925092505060005b89518110156149c8576149238982815181106148f057fe5b60200260200101516bffffffffffffffffffffffff16836bffffffffffffffffffffffff166136c490919063ffffffff16565b614965846bffffffffffffffffffffffff168c848151811061494157fe5b60200260200101516bffffffffffffffffffffffff166136c490919063ffffffff16565b106149bb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180615a9b6029913960400191505060405180910390fd5b80806001019150506148d8565b50505060006149d683611978565b91506000600260008b815260200190815260200160002060050154905060005b8951811015614c4f5760008a8281518110614a0d57fe5b60200260200101516bffffffffffffffffffffffff1611614a79576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806158956025913960400191505060405180910390fd5b81898281518110614a8657fe5b60200260200101516bffffffffffffffffffffffff1611614b0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f6f7264657220746f6f20736d616c6c000000000000000000000000000000000081525060200191505060405180910390fd5b614b79614b43858c8481518110614b2257fe5b60200260200101518c8581518110614b3657fe5b60200260200101516138da565b898381518110614b4f57fe5b6020026020010151600160008f81526020019081526020016000206150089092919063ffffffff16565b15614c4257614bb2898281518110614b8d57fe5b60200260200101516bffffffffffffffffffffffff168461363c90919063ffffffff16565b92508367ffffffffffffffff168b7f9304f2fc7ed6d42c0400e678dbc7283e1e9054889c3afea5f965adff66ef9eac8c8481518110614bed57fe5b60200260200101518c8581518110614c0157fe5b602002602001015160405180836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681526020019250505060405180910390a35b80806001019150506149f6565b50614cb3333084600260008f815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613794909392919063ffffffff16565b5050979650505050505050565b60008083118290614d6c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614d31578082015181840152602081019050614d16565b50505050905090810190601f168015614d5e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614d7857fe5b049050809150509392505050565b6060614de8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166152b69092919063ffffffff16565b9050600081511115614e7057808060200190516020811015614e0957600080fd5b8101908080519060200190929190505050614e6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615aed602a913960400191505060405180910390fd5b5b505050565b6000838311158290614f22576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614ee7578082015181840152602081019050614ecc565b50505050905090810190601f168015614f145780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000614f4183836152ce565b614fb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4d757374206861766520494420746f206765742041646472657373000000000081525060200191505060405180910390fd5b8260000160006001840167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b60008061501484613e42565b9250505060006bffffffffffffffffffffffff16816bffffffffffffffffffffffff1614156150ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e73657274696e67207a65726f206973206e6f7420737570706f727465640081525060200191505060405180910390fd5b600160001b84141580156150e257507fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b8414155b615154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e73657274696e6720656c656d656e74206973206e6f742076616c6964000081525060200191505060405180910390fd5b61515e85856141cf565b1561516d5760009150506152af565b600160001b831415801561519857506000801b85600101600085815260200190815260200160002054145b156151a75760009150506152af565b6151ba848461424890919063ffffffff16565b6151c85760009150506152af565b5b6000801b856000016000858152602001908152602001600020541415615206578460010160008481526020019081526020016000205492506151c9565b6000808490505b80915086600001600082815260200190815260200160002054905061523b868261424890919063ffffffff16565b61520d578587600001600084815260200190815260200160002081905550858760010160008381526020019081526020016000208190555081876001016000888152602001908152602001600020819055508087600001600088815260200190815260200160002081905550600193505050505b9392505050565b60606152c58484600085615354565b90509392505050565b60008073ffffffffffffffffffffffffffffffffffffffff168360000160006001850167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415905092915050565b6060824710156153af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806158dc6026913960400191505060405180910390fd5b6153b8856154fd565b61542a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061547a5780518252602082019150602081019050602083039250615457565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146154dc576040519150601f19603f3d011682016040523d82523d6000602084013e6154e1565b606091505b50915091506154f1828286615510565b92505050949350505050565b600080823b905060008111915050919050565b60608315615520578290506155d5565b6000835111156155335782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561559a57808201518184015260208101905061557f565b50505050905090810190601f1680156155c75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061561d57805160ff191683800117855561564b565b8280016001018555821561564b579182015b8281111561564a57825182559160200191906001019061562f565b5b509050615658919061575a565b5090565b50805460018160011615610100020316600290046000825580601f1061568257506156a1565b601f0160209004906000526020600020908101906156a0919061575a565b5b50565b604051806101c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600080191681526020016000815260200160008152602001600080191681526020016000801916815260200160006bffffffffffffffffffffffff16815260200160001515815260200160001515815260200160008152602001600081525090565b5b8082111561577357600081600090555060010161575b565b509056fe53616665436173743a2076616c756520646f65736e27742066697420696e20393620626974736e6f7420616c6c6f77656420746f20736574746c652061756374696f6e2061746f6d6963616c6c7970726563616c63756c61746553656c6c416d6f756e7453756d20697320616c726561647920746f6f20616476616e6365644f6e6c792074686520757365722063616e2063616e63656c20686973206f72646572734f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373746f6b656e732063616e6e6f742062652061756374696f6e656420666f7220667265656e6f206c6f6e67657220696e206f7264657220706c6163656d656e7420616e642063616e63656c6174696f6e2070686173655f6d696e427579416d6f756e7473206d7573742062652067726561746572207468616e2030547279696e6720746f20676574206e657874206f66206c61737420656c656d656e74416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c466565206973206e6f7420616c6c6f77656420746f2062652073657420686967686572207468616e20312e352561756374696f6e20656e642064617465206d75737420626520696e20746865206675747572654f6e6c79206f6e65206f726465722063616e20626520706c616365642061746f6d6963616c6c79547279696e6720746f20676574206e657874206f66206e6f6e2d6578697374656e7420656c656d656e746d696e696d756d42696464696e67416d6f756e745065724f72646572206973206e6f7420616c6c6f77656420746f206265207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7753616665436173743a2076616c756520646f65736e27742066697420696e20363420626974736f6e6c7920616c6c6f77656420746f20636c61696d20666f722073616d65207573657241756374696f6e206e6f7420696e20736f6c7574696f6e207375626d697373696f6e20706861736575736572206973206e6f7420616c6c6f77656420746f20706c6163652073616d65206f726465722074776963656c696d6974207072696365206e6f7420626574746572207468616e206d696d696d616c206f6666657274696d6520706572696f647320617265206e6f7420636f6e6669677572656420636f72726563746c795361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565646e6f206c6f6e67657220696e206f7264657220706c6163656d656e74207068617365a264697066735822122058a2e7637b1d98a0ddfe0268e46b525e60a7ab6f90293eaa1635c3bed84c68b564736f6c634300060c0033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101585760003560e01c80637882deaf116100c3578063d73792a91161007c578063d73792a914610ccf578063e4a59ef414610ced578063e86dea4a14610d45578063ec20d0bb14610d63578063f2fde38b14610fe0578063f59c2f061461102457610158565b80637882deaf146106425780637ed18b701461071f5780638da5cb5b146107e157806391cfc1d414610815578063a7e7664414610a54578063d225269c14610a7257610158565b80633e12905f116101155780633e12905f1461046157806340b20b091461049957806355fc62d2146104e75780635cefb291146105c257806363c699a4146105ea578063715018a61461063857610158565b80630a4cd6c91461015d57806315d37b4b146102f157806319a50f49146103335780632199d5cd1461035b5780632b956ff7146103bd5780632e9936111461041f575b600080fd5b6102db600480360361016081101561017457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080356bffffffffffffffffffffffff16906020019092919080356bffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190803515159060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561025557600080fd5b82018360208201111561026757600080fd5b8035906020019184600183028401116401000000008311171561028957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506110cb565b6040518082815260200191505060405180910390f35b61031d6004803603602081101561030757600080fd5b810190808035906020019092919050505061178a565b6040518082815260200191505060405180910390f35b61033b6117e4565b604051808267ffffffffffffffff16815260200191505060405180910390f35b61039d6004803603602081101561037157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506117fe565b604051808267ffffffffffffffff16815260200191505060405180910390f35b6103ff600480360360208110156103d357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611978565b604051808267ffffffffffffffff16815260200191505060405180910390f35b61044b6004803603602081101561043557600080fd5b8101908080359060200190929190505050611a0d565b6040518082815260200191505060405180910390f35b6104976004803603604081101561047757600080fd5b810190808035906020019092919080359060200190929190505050611fb4565b005b6104e5600480360360408110156104af57600080fd5b8101908080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506122d6565b005b610513600480360360208110156104fd57600080fd5b8101908080359060200190929190505050612434565b604051808f73ffffffffffffffffffffffffffffffffffffffff1681526020018e73ffffffffffffffffffffffffffffffffffffffff1681526020018d81526020018c81526020018b81526020018a8152602001898152602001888152602001878152602001866bffffffffffffffffffffffff168152602001851515815260200184151581526020018381526020018281526020019e50505050505050505050505050505060405180910390f35b6105ca612512565b604051808267ffffffffffffffff16815260200191505060405180910390f35b6106206004803603604081101561060057600080fd5b81019080803590602001909291908035906020019092919050505061252c565b60405180821515815260200191505060405180910390f35b61064061255b565b005b6107026004803603604081101561065857600080fd5b81019080803590602001909291908035906020019064010000000081111561067f57600080fd5b82018360208201111561069157600080fd5b803590602001918460208302840111640100000000831117156106b357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192905050506126e1565b604051808381526020018281526020019250505060405180910390f35b6107df6004803603604081101561073557600080fd5b81019080803590602001909291908035906020019064010000000081111561075c57600080fd5b82018360208201111561076e57600080fd5b8035906020019184602083028401116401000000008311171561079057600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290505050612d2d565b005b6107e9612f90565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610a52600480360360a081101561082b57600080fd5b81019080803590602001909291908035906020019064010000000081111561085257600080fd5b82018360208201111561086457600080fd5b8035906020019184602083028401116401000000008311171561088657600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f820116905080830192505050505050509192919290803590602001906401000000008111156108e657600080fd5b8201836020820111156108f857600080fd5b8035906020019184602083028401116401000000008311171561091a57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f8201169050808301925050505050505091929192908035906020019064010000000081111561097a57600080fd5b82018360208201111561098c57600080fd5b803590602001918460208302840111640100000000831117156109ae57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610a0e57600080fd5b820183602082011115610a2057600080fd5b80359060200191846001830284011164010000000083111715610a4257600080fd5b9091929391929390505050612fb9565b005b610a5c613221565b6040518082815260200191505060405180910390f35b610caf600480360360a0811015610a8857600080fd5b810190808035906020019092919080359060200190640100000000811115610aaf57600080fd5b820183602082011115610ac157600080fd5b80359060200191846020830284011164010000000083111715610ae357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610b4357600080fd5b820183602082011115610b5557600080fd5b80359060200191846020830284011164010000000083111715610b7757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610bd757600080fd5b820183602082011115610be957600080fd5b80359060200191846020830284011164010000000083111715610c0b57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610c6b57600080fd5b820183602082011115610c7d57600080fd5b80359060200191846001830284011164010000000083111715610c9f57600080fd5b9091929391929390505050613227565b604051808267ffffffffffffffff16815260200191505060405180910390f35b610cd76132b4565b6040518082815260200191505060405180910390f35b610d1960048036036020811015610d0357600080fd5b81019080803590602001909291905050506132ba565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610d4d6132ed565b6040518082815260200191505060405180910390f35b610fc0600480360360c0811015610d7957600080fd5b810190808035906020019092919080359060200190640100000000811115610da057600080fd5b820183602082011115610db257600080fd5b80359060200191846020830284011164010000000083111715610dd457600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610e3457600080fd5b820183602082011115610e4657600080fd5b80359060200191846020830284011164010000000083111715610e6857600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610ec857600080fd5b820183602082011115610eda57600080fd5b80359060200191846020830284011164010000000083111715610efc57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050919291929080359060200190640100000000811115610f5c57600080fd5b820183602082011115610f6e57600080fd5b80359060200191846001830284011164010000000083111715610f9057600080fd5b9091929391929390803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506132f3565b604051808267ffffffffffffffff16815260200191505060405180910390f35b61102260048036036020811015610ff657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613381565b005b6110506004803603602081101561103a57600080fd5b810190808035906020019092919050505061358c565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015611090578082015181840152602081019050611075565b50505050905090810190601f1680156110bd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000611144333061111d6103e861110f6110f26009546103e861363c90919063ffffffff16565b8e6bffffffffffffffffffffffff166136c490919063ffffffff16565b61374a90919063ffffffff16565b8f73ffffffffffffffffffffffffffffffffffffffff16613794909392919063ffffffff16565b6000886bffffffffffffffffffffffff16116111c8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f63616e6e6f742061756374696f6e207a65726f20746f6b656e7300000000000081525060200191505060405180910390fd5b6000876bffffffffffffffffffffffff161161122f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806158406023913960400191505060405180910390fd5b60008611611288576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260368152602001806159a66036913960400191505060405180910390fd5b888a11156112e1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180615ac46029913960400191505060405180910390fd5b428911611339576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061592f6026913960400191505060405180910390fd5b61134f600160085461363c90919063ffffffff16565b600881905550611372600160006008548152602001908152602001600020613855565b600061137d33611978565b9050604051806101c001604052808e73ffffffffffffffffffffffffffffffffffffffff1681526020018d73ffffffffffffffffffffffffffffffffffffffff1681526020018c81526020018b81526020016113da838b8d6138da565b815260200188815260200160008152602001600160001b81526020016000801b815260200160006bffffffffffffffffffffffff168152602001600015158152602001861515815260200160095481526020018781525060026000600854815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301556080820151816004015560a0820151816005015560c0820151816006015560e0820151816007015561010082015181600801556101208201518160090160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff16021790555061014082015181600901600c6101000a81548160ff02191690831515021790555061016082015181600901600d6101000a81548160ff02191690831515021790555061018082015181600a01556101a082015181600b01559050508360036000600854815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600460006008548152602001908152602001600020908051906020019061162b9291906155dc565b508b73ffffffffffffffffffffffffffffffffffffffff168d73ffffffffffffffffffffffffffffffffffffffff166008547f728d0fed13687f1840de94f5ae640eae49b43eda26b7ffe97e55e79a0de6e40c8e8e868f8f8f8f8e8e604051808a81526020018981526020018867ffffffffffffffff168152602001876bffffffffffffffffffffffff168152602001866bffffffffffffffffffffffff1681526020018581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611733578082015181840152602081019050611718565b50505050905090810190601f1680156117605780820380516001836020036101000a031916815260200191505b509a505050505050505050505060405180910390a46008549150509b9a5050505050505050505050565b600042600260008481526020019081526020016000206003015410156117b357600090506117df565b6117dc42600260008581526020019081526020016000206003015461391b90919063ffffffff16565b90505b919050565b600760009054906101000a900467ffffffffffffffff1681565b600061183c6118376001600760009054906101000a900467ffffffffffffffff1667ffffffffffffffff1661363c90919063ffffffff16565b613965565b600760006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550611890600760009054906101000a900467ffffffffffffffff168360056139d09092919063ffffffff16565b611902576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260178152602001807f5573657220616c7265616479207265676973746572656400000000000000000081525060200191505060405180910390fd5b600760009054906101000a900467ffffffffffffffff1690508173ffffffffffffffffffffffffffffffffffffffff167f6838f67cb358c332087b73dbe769a6c869a5f87225236c16dda5d0013a77074c82604051808267ffffffffffffffff16815260200191505060405180910390a2919050565b600061198e826005613cf690919063ffffffff16565b156119ae576119a7826005613d6390919063ffffffff16565b9050611a08565b6119b7826117fe565b90508173ffffffffffffffffffffffffffffffffffffffff168167ffffffffffffffff167f969d438b19b6b5fb3c0d3c6f16867e519fcec4233799d6be29d1c00f2045ba2660405160405180910390a35b919050565b60008160006002600083815260200190815260200160002060030154905060008114158015611a3c5750804210155b8015611a6057506000801b6002600084815260200190815260200160002060080154145b611ab5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615a466028913960400191505060405180910390fd5b506000806000611ada6002600088815260200190815260200160002060040154613e42565b92509250925060006002600088815260200190815260200160002060060154905060006002600089815260200190815260200160002060070154905060008060008590505b6000611b4685600160008f8152602001908152602001600020613e6890919063ffffffff16565b90507fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b811415611b795750611c02565b809450611b8585613e42565b909150816bffffffffffffffffffffffff169150806bffffffffffffffffffffffff1690508094508195505050611bc5838761363c90919063ffffffff16565b955050611be982876bffffffffffffffffffffffff166136c490919063ffffffff16565b611bfc84876136c490919063ffffffff16565b10611b1f575b600085118015611c445750611c2e82876bffffffffffffffffffffffff166136c490919063ffffffff16565b611c4184876136c490919063ffffffff16565b10155b15611d4d576000611c90611c8185611c73868b6bffffffffffffffffffffffff166136c490919063ffffffff16565b61374a90919063ffffffff16565b8761391b90919063ffffffff16565b9050808310611d1b576000611cae828561391b90919063ffffffff16565b9050611cb981613f66565b600260008f815260200190815260200160002060090160006101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550611d10828861391b90919063ffffffff16565b9650859b5050611d47565b611d2e838761391b90919063ffffffff16565b9550611d44600088611d3f89613f66565b6138da565b9a505b50611dd9565b866bffffffffffffffffffffffff16851115611d7e57611d77600087611d7288613f66565b6138da565b9950611dd8565b611d8a600087896138da565b9950611dd5611dd0886bffffffffffffffffffffffff16611dc2896bffffffffffffffffffffffff16896136c490919063ffffffff16565b61374a90919063ffffffff16565b613f66565b90505b5b89600260008d81526020019081526020016000206008018190555084600260008d8152602001908152602001600020600b01541115611e42576001600260008d8152602001908152602001600020600901600c6101000a81548160ff0219169083151502179055505b611e5c8b826bffffffffffffffffffffffff168a89613fd5565b8a7f4d160a2a345f2faeb9ac2e65272820b8ca5473b80aabef416bdf7e07ee7f591082878d60405180846bffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff168152602001828152602001935050505060405180910390a26000600360008d815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600460008c81526020019081526020016000206000611f32919061565c565b6000801b600260008d8152602001908152602001600020600401819055506000801b600260008d8152602001908152602001600020600701819055506000600260008d8152602001908152602001600020600601819055506000600260008d815260200190815260200160002060050181905550505050505050505050919050565b8160006002600083815260200190815260200160002060030154905060008114158015611fe15750804210155b801561200557506000801b6002600084815260200190815260200160002060080154145b61205a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615a466028913960400191505060405180910390fd5b50600061207c6002600086815260200190815260200160002060040154613e42565b9250505060006002600086815260200190815260200160002060060154905060006002600087815260200190815260200160002060070154905060005b85811015612128576120e682600160008a8152602001908152602001600020613e6890919063ffffffff16565b915060006120f383613e42565b92505050612118816bffffffffffffffffffffffff168561363c90919063ffffffff16565b93505080806001019150506120b9565b507fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b8114156121c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f7265616368656420656e64206f66206f72646572206c6973740000000000000081525060200191505060405180910390fd5b6000806121ce83613e42565b9250925050612202816bffffffffffffffffffffffff16866bffffffffffffffffffffffff166136c490919063ffffffff16565b612223836bffffffffffffffffffffffff16866136c490919063ffffffff16565b10612296576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f746f6f206d616e79206f72646572732073756d6d65642075700000000000000081525060200191505060405180910390fd5b83600260008a81526020019081526020016000206006018190555082600260008a8152602001908152602001600020600701819055505050505050505050565b6122de6141c7565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461239e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600f8211156123f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180615902602d913960400191505060405180910390fd5b61240181611978565b600a60006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550816009819055505050565b60026020528060005260406000206000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060020154908060030154908060040154908060050154908060060154908060070154908060080154908060090160009054906101000a90046bffffffffffffffffffffffff169080600901600c9054906101000a900460ff169080600901600d9054906101000a900460ff169080600a01549080600b015490508e565b600a60009054906101000a900467ffffffffffffffff1681565b600061255382600160008681526020019081526020016000206141cf90919063ffffffff16565b905092915050565b6125636141c7565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612623576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a360008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600080836000801b60026000838152602001908152602001600020600801541415612774576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f41756374696f6e206e6f74207965742066696e6973686564000000000000000081525060200191505060405180910390fd5b60005b8451811015612837576127b885828151811061278f57fe5b60200260200101516001600089815260200190815260200160002061420b90919063ffffffff16565b61282a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f6f72646572206973206e6f206c6f6e67657220636c61696d61626c650000000081525060200191505060405180910390fd5b8080600101915050612777565b506128406156a4565b60026000878152602001908152602001600020604051806101c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481526020016003820154815260200160048201548152602001600582015481526020016006820154815260200160078201548152602001600882015481526020016009820160009054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815260200160098201600c9054906101000a900460ff1615151515815260200160098201600d9054906101000a900460ff16151515158152602001600a8201548152602001600b8201548152505090506000806129ec836101000151613e42565b92509250506000612a1088600081518110612a0357fe5b6020026020010151613e42565b505090506000600260008b8152602001908152602001600020600901600c9054906101000a900460ff16905060005b8951811015612d13576000806000612a698d8581518110612a5c57fe5b6020026020010151613e42565b9250925092508567ffffffffffffffff168367ffffffffffffffff1614612adb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180615a236023913960400191505060405180910390fd5b8415612b0957612b02816bffffffffffffffffffffffff168c61363c90919063ffffffff16565b9a50612c9c565b8861010001518d8581518110612b1b57fe5b60200260200101511415612bde57612b8f612b80886bffffffffffffffffffffffff16612b728b6bffffffffffffffffffffffff168d61012001516bffffffffffffffffffffffff166136c490919063ffffffff16565b61374a90919063ffffffff16565b8d61363c90919063ffffffff16565b9b50612bd7612bc88a61012001516bffffffffffffffffffffffff16836bffffffffffffffffffffffff1661391b90919063ffffffff16565b8c61363c90919063ffffffff16565b9a50612c9b565b612c098961010001518e8681518110612bf357fe5b602002602001015161424890919063ffffffff16565b15612c7657612c6f612c60886bffffffffffffffffffffffff16612c528b6bffffffffffffffffffffffff16856bffffffffffffffffffffffff166136c490919063ffffffff16565b61374a90919063ffffffff16565b8d61363c90919063ffffffff16565b9b50612c9a565b612c97816bffffffffffffffffffffffff168c61363c90919063ffffffff16565b9a505b5b5b8567ffffffffffffffff168e7f3f2c83616e48a2f8b3c9cc26499e2e5c61643714dac49027d82cf6732f96a91a848460405180836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681526020019250505060405180910390a35050508080600101915050612a3f565b50612d208a898985614466565b5050505050509250929050565b8160026000828152602001908152602001600020600201544210612d9c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806158636032913960400191505060405180910390fd5b6000612da733611978565b90506000805b8451811015612f27576000612df0868381518110612dc757fe5b6020026020010151600160008a815260200190815260200160002061455b90919063ffffffff16565b90508015612f19576000806000612e19898681518110612e0c57fe5b6020026020010151613e42565b9250925092508667ffffffffffffffff168367ffffffffffffffff1614612e8b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806157f76023913960400191505060405180910390fd5b612eac816bffffffffffffffffffffffff168761363c90919063ffffffff16565b95508667ffffffffffffffff168a7f7edae327fe79804b2f38bd490d874a0d188d3ae8911b303205abe47400086ac4848460405180836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681526020019250505060405180910390a35050505b508080600101915050612dad565b50612f8933826002600089815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166146069092919063ffffffff16565b5050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b8560006002600083815260200190815260200160002060030154905060008114158015612fe65750804210155b801561300a57506000801b6002600084815260200190815260200160002060080154145b61305f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526028815260200180615a466028913960400191505060405180910390fd5b5060026000888152602001908152602001600020600901600d9054906101000a900460ff166130d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602881526020018061579e6028913960400191505060405180910390fd5b600186511480156130eb575060018551145b613140576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260278152602001806159556027913960400191505060405180910390fd5b600061314b33611978565b90506131a8613183828960008151811061316157fe5b60200260200101518960008151811061317657fe5b60200260200101516138da565b600260008b81526020019081526020016000206007015461424890919063ffffffff16565b6131fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260318152602001806157c66031913960400191505060405180910390fd5b61320c888888888888336146a8565b5061321688611a0d565b505050505050505050565b60085481565b60008660026000828152602001908152602001600020600301544210613298576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615b176022913960400191505060405180910390fd5b6132a7888888888888336146a8565b9150509695505050505050565b6103e881565b60036020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60095481565b60008760026000828152602001908152602001600020600301544210613364576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180615b176022913960400191505060405180910390fd5b613373898989898989896146a8565b915050979650505050505050565b6133896141c7565b73ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614613449576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156134cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061581a6026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1660008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60046020528060005260406000206000915090508054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156136345780601f1061360957610100808354040283529160200191613634565b820191906000526020600020905b81548152906001019060200180831161361757829003601f168201915b505050505081565b6000808284019050838110156136ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6000808314156136d75760009050613744565b60008284029050828482816136e857fe5b041461373f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806159dc6021913960400191505060405180910390fd5b809150505b92915050565b600061378c83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614cc0565b905092915050565b61384f846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614d86565b50505050565b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b816000016000600160001b815260200190815260200160002081905550600160001b8160010160007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b81526020019081526020016000208190555050565b6000816bffffffffffffffffffffffff166060846bffffffffffffffffffffffff16901b60c08667ffffffffffffffff16901b010160001b90509392505050565b600061395d83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614e75565b905092915050565b60006801000000000000000082106139c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806159fd6026913960400191505060405180910390fd5b819050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613a74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f43616e6e6f7420696e73657274207a65726f206164647265737300000000000081525060200191505060405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff67ffffffffffffffff168367ffffffffffffffff161415613b1e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260188152602001807f43616e6e6f7420696e73657274206d61782075696e743634000000000000000081525060200191505060405180910390fd5b60008460010160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900467ffffffffffffffff1667ffffffffffffffff16141580613c065750600073ffffffffffffffffffffffffffffffffffffffff168460000160006001860167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614155b15613c145760009050613cef565b818460000160006001860167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600183018460010160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550600190505b9392505050565b6000808360010160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900467ffffffffffffffff1667ffffffffffffffff161415905092915050565b6000613d6f8383613cf6565b613de1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4d7573742068617665204164647265737320746f20676574204944000000000081525060200191505060405180910390fd5b60018360010160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900467ffffffffffffffff1603905092915050565b600080600060c08460001c901c925060608460001c901c91508360001c90509193909250565b60007fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b821415613ee6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806158ba6022913960400191505060405180910390fd5b60008360000160008481526020019081526020016000205490506000801b811415613f5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061597c602a913960400191505060405180910390fd5b8091505092915050565b60006c010000000000000000000000008210613fcd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806157786026913960400191505060405180910390fd5b819050919050565b60006140226103e861401460026000898152602001908152602001600020600a0154856bffffffffffffffffffffffff166136c490919063ffffffff16565b61374a90919063ffffffff16565b905060026000868152602001908152602001600020600901600c9054906101000a900460ff161561407f5761407a8561407283856bffffffffffffffffffffffff1661363c90919063ffffffff16565b600086614466565b6141c0565b6000806140a16002600089815260200190815260200160002060080154613e42565b925092505060006140c987866bffffffffffffffffffffffff1661391b90919063ffffffff16565b90506000614112614103876bffffffffffffffffffffffff166140f585896136c490919063ffffffff16565b61374a90919063ffffffff16565b8361363c90919063ffffffff16565b90506000614157856bffffffffffffffffffffffff16614149866bffffffffffffffffffffffff168c6136c490919063ffffffff16565b61374a90919063ffffffff16565b90506141658a83838b614466565b6141ba8a61419c896bffffffffffffffffffffffff1661418e8d8b6136c490919063ffffffff16565b61374a90919063ffffffff16565b6000600a60009054906101000a900467ffffffffffffffff16614466565b50505050505b5050505050565b600033905090565b6000600160001b8214156141e65760009050614205565b6000801b83600001600084815260200190815260200160002054141590505b92915050565b600080614218848461455b565b9050801561423e576000801b846001016000858152602001908152602001600020819055505b8091505092915050565b60008060008061425786613e42565b925092509250600080600061426b88613e42565b9250925092506142a0846bffffffffffffffffffffffff16836bffffffffffffffffffffffff166136c490919063ffffffff16565b6142cf826bffffffffffffffffffffffff16876bffffffffffffffffffffffff166136c490919063ffffffff16565b10156142e45760019650505050505050614460565b614313846bffffffffffffffffffffffff16836bffffffffffffffffffffffff166136c490919063ffffffff16565b614342826bffffffffffffffffffffffff16876bffffffffffffffffffffffff166136c490919063ffffffff16565b11156143575760009650505050505050614460565b816bffffffffffffffffffffffff16856bffffffffffffffffffffffff16101561438a5760019650505050505050614460565b816bffffffffffffffffffffffff16856bffffffffffffffffffffffff1611156143bd5760009650505050505050614460565b8267ffffffffffffffff168667ffffffffffffffff16141561442a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180615a6e602d913960400191505060405180910390fd5b8267ffffffffffffffff168667ffffffffffffffff1610156144555760019650505050505050614460565b600096505050505050505b92915050565b600061447c826005614f3590919063ffffffff16565b905060008411156144e9576144e881856002600089815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166146069092919063ffffffff16565b5b60008311156145545761455381846002600089815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166146069092919063ffffffff16565b5b5050505050565b600061456783836141cf565b6145745760009050614600565b60008360010160008481526020019081526020016000205490506000846000016000858152602001908152602001600020549050808560000160008481526020019081526020016000208190555081856001016000838152602001908152602001600020819055506000801b856000016000868152602001908152602001600020819055506001925050505b92915050565b6146a38363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614d86565b505050565b600080600360008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146148ad576319a05a7e60e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168173ffffffffffffffffffffffffffffffffffffffff166319a05a7e858c89896040518563ffffffff1660e01b8152600401808573ffffffffffffffffffffffffffffffffffffffff168152602001848152602001806020018281038252848482818152602001925080828437600081840152601f19601f8201169050808301925050509550505050505060206040518083038186803b1580156147df57600080fd5b505afa1580156147f3573d6000803e3d6000fd5b505050506040513d602081101561480957600080fd5b81019080805190602001909291905050507bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146148ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f75736572206e6f7420616c6c6f77656420746f20706c616365206f726465720081525060200191505060405180910390fd5b5b506000806148d0600260008c815260200190815260200160002060040154613e42565b925092505060005b89518110156149c8576149238982815181106148f057fe5b60200260200101516bffffffffffffffffffffffff16836bffffffffffffffffffffffff166136c490919063ffffffff16565b614965846bffffffffffffffffffffffff168c848151811061494157fe5b60200260200101516bffffffffffffffffffffffff166136c490919063ffffffff16565b106149bb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180615a9b6029913960400191505060405180910390fd5b80806001019150506148d8565b50505060006149d683611978565b91506000600260008b815260200190815260200160002060050154905060005b8951811015614c4f5760008a8281518110614a0d57fe5b60200260200101516bffffffffffffffffffffffff1611614a79576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806158956025913960400191505060405180910390fd5b81898281518110614a8657fe5b60200260200101516bffffffffffffffffffffffff1611614b0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f6f7264657220746f6f20736d616c6c000000000000000000000000000000000081525060200191505060405180910390fd5b614b79614b43858c8481518110614b2257fe5b60200260200101518c8581518110614b3657fe5b60200260200101516138da565b898381518110614b4f57fe5b6020026020010151600160008f81526020019081526020016000206150089092919063ffffffff16565b15614c4257614bb2898281518110614b8d57fe5b60200260200101516bffffffffffffffffffffffff168461363c90919063ffffffff16565b92508367ffffffffffffffff168b7f9304f2fc7ed6d42c0400e678dbc7283e1e9054889c3afea5f965adff66ef9eac8c8481518110614bed57fe5b60200260200101518c8581518110614c0157fe5b602002602001015160405180836bffffffffffffffffffffffff168152602001826bffffffffffffffffffffffff1681526020019250505060405180910390a35b80806001019150506149f6565b50614cb3333084600260008f815260200190815260200160002060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613794909392919063ffffffff16565b5050979650505050505050565b60008083118290614d6c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614d31578082015181840152602081019050614d16565b50505050905090810190601f168015614d5e5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614d7857fe5b049050809150509392505050565b6060614de8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166152b69092919063ffffffff16565b9050600081511115614e7057808060200190516020811015614e0957600080fd5b8101908080519060200190929190505050614e6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615aed602a913960400191505060405180910390fd5b5b505050565b6000838311158290614f22576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614ee7578082015181840152602081019050614ecc565b50505050905090810190601f168015614f145780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000614f4183836152ce565b614fb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f4d757374206861766520494420746f206765742041646472657373000000000081525060200191505060405180910390fd5b8260000160006001840167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905092915050565b60008061501484613e42565b9250505060006bffffffffffffffffffffffff16816bffffffffffffffffffffffff1614156150ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f496e73657274696e67207a65726f206973206e6f7420737570706f727465640081525060200191505060405180910390fd5b600160001b84141580156150e257507fffffffffffffffffffffffffffffffffffffffff00000000000000000000000160001b8414155b615154576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f496e73657274696e6720656c656d656e74206973206e6f742076616c6964000081525060200191505060405180910390fd5b61515e85856141cf565b1561516d5760009150506152af565b600160001b831415801561519857506000801b85600101600085815260200190815260200160002054145b156151a75760009150506152af565b6151ba848461424890919063ffffffff16565b6151c85760009150506152af565b5b6000801b856000016000858152602001908152602001600020541415615206578460010160008481526020019081526020016000205492506151c9565b6000808490505b80915086600001600082815260200190815260200160002054905061523b868261424890919063ffffffff16565b61520d578587600001600084815260200190815260200160002081905550858760010160008381526020019081526020016000208190555081876001016000888152602001908152602001600020819055508087600001600088815260200190815260200160002081905550600193505050505b9392505050565b60606152c58484600085615354565b90509392505050565b60008073ffffffffffffffffffffffffffffffffffffffff168360000160006001850167ffffffffffffffff1667ffffffffffffffff16815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415905092915050565b6060824710156153af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806158dc6026913960400191505060405180910390fd5b6153b8856154fd565b61542a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061547a5780518252602082019150602081019050602083039250615457565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d80600081146154dc576040519150601f19603f3d011682016040523d82523d6000602084013e6154e1565b606091505b50915091506154f1828286615510565b92505050949350505050565b600080823b905060008111915050919050565b60608315615520578290506155d5565b6000835111156155335782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561559a57808201518184015260208101905061557f565b50505050905090810190601f1680156155c75780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061561d57805160ff191683800117855561564b565b8280016001018555821561564b579182015b8281111561564a57825182559160200191906001019061562f565b5b509050615658919061575a565b5090565b50805460018160011615610100020316600290046000825580601f1061568257506156a1565b601f0160209004906000526020600020908101906156a0919061575a565b5b50565b604051806101c00160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000815260200160008152602001600080191681526020016000815260200160008152602001600080191681526020016000801916815260200160006bffffffffffffffffffffffff16815260200160001515815260200160001515815260200160008152602001600081525090565b5b8082111561577357600081600090555060010161575b565b509056fe53616665436173743a2076616c756520646f65736e27742066697420696e20393620626974736e6f7420616c6c6f77656420746f20736574746c652061756374696f6e2061746f6d6963616c6c7970726563616c63756c61746553656c6c416d6f756e7453756d20697320616c726561647920746f6f20616476616e6365644f6e6c792074686520757365722063616e2063616e63656c20686973206f72646572734f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373746f6b656e732063616e6e6f742062652061756374696f6e656420666f7220667265656e6f206c6f6e67657220696e206f7264657220706c6163656d656e7420616e642063616e63656c6174696f6e2070686173655f6d696e427579416d6f756e7473206d7573742062652067726561746572207468616e2030547279696e6720746f20676574206e657874206f66206c61737420656c656d656e74416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c466565206973206e6f7420616c6c6f77656420746f2062652073657420686967686572207468616e20312e352561756374696f6e20656e642064617465206d75737420626520696e20746865206675747572654f6e6c79206f6e65206f726465722063616e20626520706c616365642061746f6d6963616c6c79547279696e6720746f20676574206e657874206f66206e6f6e2d6578697374656e7420656c656d656e746d696e696d756d42696464696e67416d6f756e745065724f72646572206973206e6f7420616c6c6f77656420746f206265207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7753616665436173743a2076616c756520646f65736e27742066697420696e20363420626974736f6e6c7920616c6c6f77656420746f20636c61696d20666f722073616d65207573657241756374696f6e206e6f7420696e20736f6c7574696f6e207375626d697373696f6e20706861736575736572206973206e6f7420616c6c6f77656420746f20706c6163652073616d65206f726465722074776963656c696d6974207072696365206e6f7420626574746572207468616e206d696d696d616c206f6666657274696d6520706572696f647320617265206e6f7420636f6e6669677572656420636f72726563746c795361666545524332303a204552433230206f7065726174696f6e20646964206e6f7420737563636565646e6f206c6f6e67657220696e206f7264657220706c6163656d656e74207068617365a264697066735822122058a2e7637b1d98a0ddfe0268e46b525e60a7ab6f90293eaa1635c3bed84c68b564736f6c634300060c0033", + "devdoc": { + "kind": "dev", + "methods": { + "owner()": { + "details": "Returns the address of the current owner." + }, + "renounceOwnership()": { + "details": "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." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 30, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "_owner", + "offset": 0, + "slot": "0", + "type": "t_address" + }, + { + "astId": 1675, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "sellOrders", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_uint256,t_struct(Data)3614_storage)" + }, + { + "astId": 1679, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "auctionData", + "offset": 0, + "slot": "2", + "type": "t_mapping(t_uint256,t_struct(AuctionData)1671_storage)" + }, + { + "astId": 1683, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "auctionAccessManager", + "offset": 0, + "slot": "3", + "type": "t_mapping(t_uint256,t_address)" + }, + { + "astId": 1687, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "auctionAccessData", + "offset": 0, + "slot": "4", + "type": "t_mapping(t_uint256,t_bytes_storage)" + }, + { + "astId": 1689, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "registeredUsers", + "offset": 0, + "slot": "5", + "type": "t_struct(Data)3423_storage" + }, + { + "astId": 1691, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "numUsers", + "offset": 0, + "slot": "7", + "type": "t_uint64" + }, + { + "astId": 1693, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "auctionCounter", + "offset": 0, + "slot": "8", + "type": "t_uint256" + }, + { + "astId": 1702, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "feeNumerator", + "offset": 0, + "slot": "9", + "type": "t_uint256" + }, + { + "astId": 1708, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "feeReceiverUserId", + "offset": 0, + "slot": "10", + "type": "t_uint64" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_bytes_storage": { + "encoding": "bytes", + "label": "bytes", + "numberOfBytes": "32" + }, + "t_contract(IERC20)981": { + "encoding": "inplace", + "label": "contract IERC20", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_uint64)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint64)", + "numberOfBytes": "32", + "value": "t_uint64" + }, + "t_mapping(t_bytes32,t_bytes32)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => bytes32)", + "numberOfBytes": "32", + "value": "t_bytes32" + }, + "t_mapping(t_uint256,t_address)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_mapping(t_uint256,t_bytes_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => bytes)", + "numberOfBytes": "32", + "value": "t_bytes_storage" + }, + "t_mapping(t_uint256,t_struct(AuctionData)1671_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct EasyAuction.AuctionData)", + "numberOfBytes": "32", + "value": "t_struct(AuctionData)1671_storage" + }, + "t_mapping(t_uint256,t_struct(Data)3614_storage)": { + "encoding": "mapping", + "key": "t_uint256", + "label": "mapping(uint256 => struct IterableOrderedOrderSet.Data)", + "numberOfBytes": "32", + "value": "t_struct(Data)3614_storage" + }, + "t_mapping(t_uint64,t_address)": { + "encoding": "mapping", + "key": "t_uint64", + "label": "mapping(uint64 => address)", + "numberOfBytes": "32", + "value": "t_address" + }, + "t_struct(AuctionData)1671_storage": { + "encoding": "inplace", + "label": "struct EasyAuction.AuctionData", + "members": [ + { + "astId": 1644, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "auctioningToken", + "offset": 0, + "slot": "0", + "type": "t_contract(IERC20)981" + }, + { + "astId": 1646, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "biddingToken", + "offset": 0, + "slot": "1", + "type": "t_contract(IERC20)981" + }, + { + "astId": 1648, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "orderCancellationEndDate", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 1650, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "auctionEndDate", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 1652, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "initialAuctionOrder", + "offset": 0, + "slot": "4", + "type": "t_bytes32" + }, + { + "astId": 1654, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "minimumBiddingAmountPerOrder", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 1656, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "interimSumBidAmount", + "offset": 0, + "slot": "6", + "type": "t_uint256" + }, + { + "astId": 1658, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "interimOrder", + "offset": 0, + "slot": "7", + "type": "t_bytes32" + }, + { + "astId": 1660, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "clearingPriceOrder", + "offset": 0, + "slot": "8", + "type": "t_bytes32" + }, + { + "astId": 1662, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "volumeClearingPriceOrder", + "offset": 0, + "slot": "9", + "type": "t_uint96" + }, + { + "astId": 1664, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "minFundingThresholdNotReached", + "offset": 12, + "slot": "9", + "type": "t_bool" + }, + { + "astId": 1666, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "isAtomicClosureAllowed", + "offset": 13, + "slot": "9", + "type": "t_bool" + }, + { + "astId": 1668, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "feeNumerator", + "offset": 0, + "slot": "10", + "type": "t_uint256" + }, + { + "astId": 1670, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "minFundingThreshold", + "offset": 0, + "slot": "11", + "type": "t_uint256" + } + ], + "numberOfBytes": "384" + }, + "t_struct(Data)3423_storage": { + "encoding": "inplace", + "label": "struct IdToAddressBiMap.Data", + "members": [ + { + "astId": 3418, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "idToAddress", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_uint64,t_address)" + }, + { + "astId": 3422, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "addressToId", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_uint64)" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Data)3614_storage": { + "encoding": "inplace", + "label": "struct IterableOrderedOrderSet.Data", + "members": [ + { + "astId": 3609, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "nextMap", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_bytes32,t_bytes32)" + }, + { + "astId": 3613, + "contract": "contracts/EasyAuction.sol:EasyAuction", + "label": "prevMap", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_bytes32)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + }, + "t_uint96": { + "encoding": "inplace", + "label": "uint96", + "numberOfBytes": "12" + } + } + } +} \ No newline at end of file diff --git a/deployments/binancesmartchaintestnet/solcInputs/a81c49f8848cbbe2b3d955ebaff2de99.json b/deployments/binancesmartchaintestnet/solcInputs/a81c49f8848cbbe2b3d955ebaff2de99.json new file mode 100644 index 0000000..dcdabed --- /dev/null +++ b/deployments/binancesmartchaintestnet/solcInputs/a81c49f8848cbbe2b3d955ebaff2de99.json @@ -0,0 +1,89 @@ +{ + "language": "Solidity", + "sources": { + "contracts/allowListExamples/AllowListOffChainManaged.sol": { + "content": "pragma solidity >=0.6.8;\nimport \"../interfaces/AllowListVerifier.sol\";\nimport \"../EasyAuction.sol\";\n\n// Idea was first mentioned in the blog:\n// https://medium.com/@PhABC/off-chain-whitelist-with-on-chain-verification-for-ethereum-smart-contracts-1563ca4b8f11\n\ncontract AllowListOffChainManaged {\n /// @dev The EIP-712 domain type hash used for computing the domain\n /// separator.\n bytes32 private constant DOMAIN_TYPE_HASH =\n keccak256(\n \"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\"\n );\n\n /// @dev The EIP-712 domain name used for computing the domain separator.\n bytes32 private constant DOMAIN_NAME = keccak256(\"AccessManager\");\n\n /// @dev The EIP-712 domain version used for computing the domain separator.\n bytes32 private constant DOMAIN_VERSION = keccak256(\"v1\");\n\n /// @dev The domain separator used for signing orders that gets mixed in\n /// making signatures for different domains incompatible. This domain\n /// separator is computed following the EIP-712 standard and has replay\n /// protection mixed in so that signed orders are only valid for specific\n /// GPv2 contracts.\n bytes32 public immutable domainSeparator;\n\n constructor() public {\n // NOTE: Currently, the only way to get the chain ID in solidity is\n // using assembly.\n uint256 chainId;\n // solhint-disable-next-line no-inline-assembly\n assembly {\n chainId := chainid()\n }\n\n domainSeparator = keccak256(\n abi.encode(\n DOMAIN_TYPE_HASH,\n DOMAIN_NAME,\n DOMAIN_VERSION,\n chainId,\n address(this)\n )\n );\n }\n\n function isAllowed(\n address user,\n uint256 auctionId,\n bytes calldata callData\n ) external view returns (bytes4) {\n return isAllowedBy(user, auctionId, msg.sender, callData);\n }\n\n function isAllowedBy(\n address user,\n uint256 auctionId,\n address allower,\n bytes calldata callData\n ) public view returns (bytes4) {\n uint8 v;\n bytes32 r;\n bytes32 s;\n (v, r, s) = abi.decode(callData, (uint8, bytes32, bytes32));\n bytes32 hash = keccak256(abi.encode(domainSeparator, user, auctionId));\n address signer =\n ecrecover(\n keccak256(\n abi.encodePacked(\"\\x19Ethereum Signed Message:\\n32\", hash)\n ),\n v,\n r,\n s\n );\n bytes memory allowListData =\n EasyAuction(allower).auctionAccessData(auctionId);\n if (abi.decode(allowListData, (address)) == signer) {\n return AllowListVerifierHelper.MAGICVALUE;\n } else {\n return bytes4(0);\n }\n }\n}\n" + }, + "contracts/interfaces/AllowListVerifier.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.6.8;\n\nlibrary AllowListVerifierHelper {\n /// @dev Value returned by a call to `isAllowed` if the check\n /// was successful. The value is defined as:\n /// bytes4(keccak256(\"isAllowed(address,uint256,bytes)\"))\n bytes4 internal constant MAGICVALUE = 0x19a05a7e;\n}\n\n///\n/// @dev Standardized interface for an allowList manager for easyAuction\n/// The interface was inspired by EIP-1271\ninterface AllowListVerifier {\n /// @dev Should return whether the a specific user has access to an auction\n /// by returning the magic value from AllowListVerifierHelper\n function isAllowed(\n address user,\n uint256 auctionId,\n bytes calldata callData\n ) external view returns (bytes4);\n}\n" + }, + "contracts/EasyAuction.sol": { + "content": "pragma solidity >=0.6.8;\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\";\nimport \"./libraries/IterableOrderedOrderSet.sol\";\nimport \"@openzeppelin/contracts/math/Math.sol\";\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\nimport \"./libraries/IdToAddressBiMap.sol\";\nimport \"./libraries/SafeCast.sol\";\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./interfaces/AllowListVerifier.sol\";\n\ncontract EasyAuction is Ownable {\n using SafeERC20 for IERC20;\n using SafeMath for uint64;\n using SafeMath for uint96;\n using SafeMath for uint256;\n using SafeCast for uint256;\n using IterableOrderedOrderSet for IterableOrderedOrderSet.Data;\n using IterableOrderedOrderSet for bytes32;\n using IdToAddressBiMap for IdToAddressBiMap.Data;\n\n modifier atStageOrderPlacement(uint256 auctionId) {\n require(\n block.timestamp < auctionData[auctionId].auctionEndDate,\n \"no longer in order placement phase\"\n );\n _;\n }\n\n modifier atStageOrderPlacementAndCancelation(uint256 auctionId) {\n require(\n block.timestamp < auctionData[auctionId].orderCancellationEndDate,\n \"no longer in order placement and cancelation phase\"\n );\n _;\n }\n\n modifier atStageSolutionSubmission(uint256 auctionId) {\n {\n uint256 auctionEndDate = auctionData[auctionId].auctionEndDate;\n require(\n auctionEndDate != 0 &&\n block.timestamp >= auctionEndDate &&\n auctionData[auctionId].clearingPriceOrder == bytes32(0),\n \"Auction not in solution submission phase\"\n );\n }\n _;\n }\n\n modifier atStageFinished(uint256 auctionId) {\n require(\n auctionData[auctionId].clearingPriceOrder != bytes32(0),\n \"Auction not yet finished\"\n );\n _;\n }\n\n event NewSellOrder(\n uint256 indexed auctionId,\n uint64 indexed userId,\n uint96 buyAmount,\n uint96 sellAmount\n );\n event CancellationSellOrder(\n uint256 indexed auctionId,\n uint64 indexed userId,\n uint96 buyAmount,\n uint96 sellAmount\n );\n event ClaimedFromOrder(\n uint256 indexed auctionId,\n uint64 indexed userId,\n uint96 buyAmount,\n uint96 sellAmount\n );\n event NewUser(uint64 indexed userId, address indexed userAddress);\n event NewAuction(\n uint256 indexed auctionId,\n IERC20 indexed _auctioningToken,\n IERC20 indexed _biddingToken,\n uint256 orderCancellationEndDate,\n uint256 auctionEndDate,\n uint64 userId,\n uint96 _auctionedSellAmount,\n uint96 _minBuyAmount,\n uint256 minimumBiddingAmountPerOrder,\n uint256 minFundingThreshold,\n address allowListContract,\n bytes allowListData\n );\n event AuctionCleared(\n uint256 indexed auctionId,\n uint96 soldAuctioningTokens,\n uint96 soldBiddingTokens,\n bytes32 clearingPriceOrder\n );\n event UserRegistration(address indexed user, uint64 userId);\n\n struct AuctionData {\n IERC20 auctioningToken;\n IERC20 biddingToken;\n uint256 orderCancellationEndDate;\n uint256 auctionEndDate;\n bytes32 initialAuctionOrder;\n uint256 minimumBiddingAmountPerOrder;\n uint256 interimSumBidAmount;\n bytes32 interimOrder;\n bytes32 clearingPriceOrder;\n uint96 volumeClearingPriceOrder;\n bool minFundingThresholdNotReached;\n bool isAtomicClosureAllowed;\n uint256 feeNumerator;\n uint256 minFundingThreshold;\n }\n mapping(uint256 => IterableOrderedOrderSet.Data) internal sellOrders;\n mapping(uint256 => AuctionData) public auctionData;\n mapping(uint256 => address) public auctionAccessManager;\n mapping(uint256 => bytes) public auctionAccessData;\n\n IdToAddressBiMap.Data private registeredUsers;\n uint64 public numUsers;\n uint256 public auctionCounter;\n\n constructor() public Ownable() {}\n\n uint256 public feeNumerator = 0;\n uint256 public constant FEE_DENOMINATOR = 1000;\n uint64 public feeReceiverUserId = 1;\n\n function setFeeParameters(\n uint256 newFeeNumerator,\n address newfeeReceiverAddress\n ) public onlyOwner() {\n require(\n newFeeNumerator <= 15,\n \"Fee is not allowed to be set higher than 1.5%\"\n );\n // caution: for currently running auctions, the feeReceiverUserId is changing as well.\n feeReceiverUserId = getUserId(newfeeReceiverAddress);\n feeNumerator = newFeeNumerator;\n }\n\n // @dev: function to intiate a new auction\n // Warning: In case the auction is expected to raise more than\n // 2^96 units of the biddingToken, don't start the auction, as\n // it will not be settlable. This corresponds to about 79\n // billion DAI.\n //\n // Prices between biddingToken and auctioningToken are expressed by a\n // fraction whose components are stored as uint96.\n function initiateAuction(\n IERC20 _auctioningToken,\n IERC20 _biddingToken,\n uint256 orderCancellationEndDate,\n uint256 auctionEndDate,\n uint96 _auctionedSellAmount,\n uint96 _minBuyAmount,\n uint256 minimumBiddingAmountPerOrder,\n uint256 minFundingThreshold,\n bool isAtomicClosureAllowed,\n address accessManagerContract,\n bytes memory accessManagerContractData\n ) public returns (uint256) {\n // withdraws sellAmount + fees\n _auctioningToken.safeTransferFrom(\n msg.sender,\n address(this),\n _auctionedSellAmount.mul(FEE_DENOMINATOR.add(feeNumerator)).div(\n FEE_DENOMINATOR\n ) //[0]\n );\n require(_auctionedSellAmount > 0, \"cannot auction zero tokens\");\n require(_minBuyAmount > 0, \"tokens cannot be auctioned for free\");\n require(\n minimumBiddingAmountPerOrder > 0,\n \"minimumBiddingAmountPerOrder is not allowed to be zero\"\n );\n require(\n orderCancellationEndDate <= auctionEndDate,\n \"time periods are not configured correctly\"\n );\n require(\n auctionEndDate > block.timestamp,\n \"auction end date must be in the future\"\n );\n auctionCounter = auctionCounter.add(1);\n sellOrders[auctionCounter].initializeEmptyList();\n uint64 userId = getUserId(msg.sender);\n auctionData[auctionCounter] = AuctionData(\n _auctioningToken,\n _biddingToken,\n orderCancellationEndDate,\n auctionEndDate,\n IterableOrderedOrderSet.encodeOrder(\n userId,\n _minBuyAmount,\n _auctionedSellAmount\n ),\n minimumBiddingAmountPerOrder,\n 0,\n IterableOrderedOrderSet.QUEUE_START,\n bytes32(0),\n 0,\n false,\n isAtomicClosureAllowed,\n feeNumerator,\n minFundingThreshold\n );\n auctionAccessManager[auctionCounter] = accessManagerContract;\n auctionAccessData[auctionCounter] = accessManagerContractData;\n emit NewAuction(\n auctionCounter,\n _auctioningToken,\n _biddingToken,\n orderCancellationEndDate,\n auctionEndDate,\n userId,\n _auctionedSellAmount,\n _minBuyAmount,\n minimumBiddingAmountPerOrder,\n minFundingThreshold,\n accessManagerContract,\n accessManagerContractData\n );\n return auctionCounter;\n }\n\n function placeSellOrders(\n uint256 auctionId,\n uint96[] memory _minBuyAmounts,\n uint96[] memory _sellAmounts,\n bytes32[] memory _prevSellOrders,\n bytes calldata allowListCallData\n ) external atStageOrderPlacement(auctionId) returns (uint64 userId) {\n return\n _placeSellOrders(\n auctionId,\n _minBuyAmounts,\n _sellAmounts,\n _prevSellOrders,\n allowListCallData,\n msg.sender\n );\n }\n\n function placeSellOrdersOnBehalf(\n uint256 auctionId,\n uint96[] memory _minBuyAmounts,\n uint96[] memory _sellAmounts,\n bytes32[] memory _prevSellOrders,\n bytes calldata allowListCallData,\n address orderSubmitter\n ) external atStageOrderPlacement(auctionId) returns (uint64 userId) {\n return\n _placeSellOrders(\n auctionId,\n _minBuyAmounts,\n _sellAmounts,\n _prevSellOrders,\n allowListCallData,\n orderSubmitter\n );\n }\n\n function _placeSellOrders(\n uint256 auctionId,\n uint96[] memory _minBuyAmounts,\n uint96[] memory _sellAmounts,\n bytes32[] memory _prevSellOrders,\n bytes calldata allowListCallData,\n address orderSubmitter\n ) internal returns (uint64 userId) {\n {\n address allowListManager = auctionAccessManager[auctionId];\n if (allowListManager != address(0)) {\n require(\n AllowListVerifier(allowListManager).isAllowed(\n orderSubmitter,\n auctionId,\n allowListCallData\n ) == AllowListVerifierHelper.MAGICVALUE,\n \"user not allowed to place order\"\n );\n }\n }\n {\n (\n ,\n uint96 buyAmountOfInitialAuctionOrder,\n uint96 sellAmountOfInitialAuctionOrder\n ) = auctionData[auctionId].initialAuctionOrder.decodeOrder();\n for (uint256 i = 0; i < _minBuyAmounts.length; i++) {\n require(\n _minBuyAmounts[i].mul(buyAmountOfInitialAuctionOrder) <\n sellAmountOfInitialAuctionOrder.mul(_sellAmounts[i]),\n \"limit price not better than mimimal offer\"\n );\n }\n }\n uint256 sumOfSellAmounts = 0;\n userId = getUserId(orderSubmitter);\n uint256 minimumBiddingAmountPerOrder =\n auctionData[auctionId].minimumBiddingAmountPerOrder;\n for (uint256 i = 0; i < _minBuyAmounts.length; i++) {\n require(\n _minBuyAmounts[i] > 0,\n \"_minBuyAmounts must be greater than 0\"\n );\n // orders should have a minimum bid size in order to limit the gas\n // required to compute the final price of the auction.\n require(\n _sellAmounts[i] > minimumBiddingAmountPerOrder,\n \"order too small\"\n );\n if (\n sellOrders[auctionId].insert(\n IterableOrderedOrderSet.encodeOrder(\n userId,\n _minBuyAmounts[i],\n _sellAmounts[i]\n ),\n _prevSellOrders[i]\n )\n ) {\n sumOfSellAmounts = sumOfSellAmounts.add(_sellAmounts[i]);\n emit NewSellOrder(\n auctionId,\n userId,\n _minBuyAmounts[i],\n _sellAmounts[i]\n );\n }\n }\n auctionData[auctionId].biddingToken.safeTransferFrom(\n msg.sender,\n address(this),\n sumOfSellAmounts\n ); //[1]\n }\n\n function cancelSellOrders(uint256 auctionId, bytes32[] memory _sellOrders)\n public\n atStageOrderPlacementAndCancelation(auctionId)\n {\n uint64 userId = getUserId(msg.sender);\n uint256 claimableAmount = 0;\n for (uint256 i = 0; i < _sellOrders.length; i++) {\n // Note: we keep the back pointer of the deleted element so that\n // it can be used as a reference point to insert a new node.\n bool success =\n sellOrders[auctionId].removeKeepHistory(_sellOrders[i]);\n if (success) {\n (\n uint64 userIdOfIter,\n uint96 buyAmountOfIter,\n uint96 sellAmountOfIter\n ) = _sellOrders[i].decodeOrder();\n require(\n userIdOfIter == userId,\n \"Only the user can cancel his orders\"\n );\n claimableAmount = claimableAmount.add(sellAmountOfIter);\n emit CancellationSellOrder(\n auctionId,\n userId,\n buyAmountOfIter,\n sellAmountOfIter\n );\n }\n }\n auctionData[auctionId].biddingToken.safeTransfer(\n msg.sender,\n claimableAmount\n ); //[2]\n }\n\n function precalculateSellAmountSum(\n uint256 auctionId,\n uint256 iterationSteps\n ) public atStageSolutionSubmission(auctionId) {\n (, , uint96 auctioneerSellAmount) =\n auctionData[auctionId].initialAuctionOrder.decodeOrder();\n uint256 sumBidAmount = auctionData[auctionId].interimSumBidAmount;\n bytes32 iterOrder = auctionData[auctionId].interimOrder;\n\n for (uint256 i = 0; i < iterationSteps; i++) {\n iterOrder = sellOrders[auctionId].next(iterOrder);\n (, , uint96 sellAmountOfIter) = iterOrder.decodeOrder();\n sumBidAmount = sumBidAmount.add(sellAmountOfIter);\n }\n\n require(\n iterOrder != IterableOrderedOrderSet.QUEUE_END,\n \"reached end of order list\"\n );\n\n // it is checked that not too many iteration steps were taken:\n // require that the sum of SellAmounts times the price of the last order\n // is not more than initially sold amount\n (, uint96 buyAmountOfIter, uint96 sellAmountOfIter) =\n iterOrder.decodeOrder();\n require(\n sumBidAmount.mul(buyAmountOfIter) <\n auctioneerSellAmount.mul(sellAmountOfIter),\n \"too many orders summed up\"\n );\n\n auctionData[auctionId].interimSumBidAmount = sumBidAmount;\n auctionData[auctionId].interimOrder = iterOrder;\n }\n\n function settleAuctionAtomically(\n uint256 auctionId,\n uint96[] memory _minBuyAmount,\n uint96[] memory _sellAmount,\n bytes32[] memory _prevSellOrder,\n bytes calldata allowListCallData\n ) public atStageSolutionSubmission(auctionId) {\n require(\n auctionData[auctionId].isAtomicClosureAllowed,\n \"not allowed to settle auction atomically\"\n );\n require(\n _minBuyAmount.length == 1 && _sellAmount.length == 1,\n \"Only one order can be placed atomically\"\n );\n uint64 userId = getUserId(msg.sender);\n require(\n auctionData[auctionId].interimOrder.smallerThan(\n IterableOrderedOrderSet.encodeOrder(\n userId,\n _minBuyAmount[0],\n _sellAmount[0]\n )\n ),\n \"precalculateSellAmountSum is already too advanced\"\n );\n _placeSellOrders(\n auctionId,\n _minBuyAmount,\n _sellAmount,\n _prevSellOrder,\n allowListCallData,\n msg.sender\n );\n settleAuction(auctionId);\n }\n\n // @dev function settling the auction and calculating the price\n function settleAuction(uint256 auctionId)\n public\n atStageSolutionSubmission(auctionId)\n returns (bytes32 clearingOrder)\n {\n (\n uint64 auctioneerId,\n uint96 minAuctionedBuyAmount,\n uint96 fullAuctionedAmount\n ) = auctionData[auctionId].initialAuctionOrder.decodeOrder();\n\n uint256 currentBidSum = auctionData[auctionId].interimSumBidAmount;\n bytes32 currentOrder = auctionData[auctionId].interimOrder;\n uint256 buyAmountOfIter;\n uint256 sellAmountOfIter;\n uint96 fillVolumeOfAuctioneerOrder = fullAuctionedAmount;\n // Sum order up, until fullAuctionedAmount is fully bought or queue end is reached\n do {\n bytes32 nextOrder = sellOrders[auctionId].next(currentOrder);\n if (nextOrder == IterableOrderedOrderSet.QUEUE_END) {\n break;\n }\n currentOrder = nextOrder;\n (, buyAmountOfIter, sellAmountOfIter) = currentOrder.decodeOrder();\n currentBidSum = currentBidSum.add(sellAmountOfIter);\n } while (\n currentBidSum.mul(buyAmountOfIter) <\n fullAuctionedAmount.mul(sellAmountOfIter)\n );\n\n if (\n currentBidSum > 0 &&\n currentBidSum.mul(buyAmountOfIter) >=\n fullAuctionedAmount.mul(sellAmountOfIter)\n ) {\n // All considered/summed orders are sufficient to close the auction fully\n // at price between current and previous orders.\n uint256 uncoveredBids =\n currentBidSum.sub(\n fullAuctionedAmount.mul(sellAmountOfIter).div(\n buyAmountOfIter\n )\n );\n\n if (sellAmountOfIter >= uncoveredBids) {\n //[13]\n // Auction fully filled via partial match of currentOrder\n uint256 sellAmountClearingOrder =\n sellAmountOfIter.sub(uncoveredBids);\n auctionData[auctionId]\n .volumeClearingPriceOrder = sellAmountClearingOrder\n .toUint96();\n currentBidSum = currentBidSum.sub(uncoveredBids);\n clearingOrder = currentOrder;\n } else {\n //[14]\n // Auction fully filled via price strictly between currentOrder and the order\n // immediately before. For a proof, see the security-considerations.md\n currentBidSum = currentBidSum.sub(sellAmountOfIter);\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\n 0,\n fullAuctionedAmount,\n currentBidSum.toUint96()\n );\n }\n } else {\n // All considered/summed orders are not sufficient to close the auction fully at price of last order //[18]\n // Either a higher price must be used or auction is only partially filled\n\n if (currentBidSum > minAuctionedBuyAmount) {\n //[15]\n // Price higher than last order would fill the auction\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\n 0,\n fullAuctionedAmount,\n currentBidSum.toUint96()\n );\n } else {\n //[16]\n // Even at the initial auction price, the auction is partially filled\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\n 0,\n fullAuctionedAmount,\n minAuctionedBuyAmount\n );\n fillVolumeOfAuctioneerOrder = currentBidSum\n .mul(fullAuctionedAmount)\n .div(minAuctionedBuyAmount)\n .toUint96();\n }\n }\n auctionData[auctionId].clearingPriceOrder = clearingOrder;\n\n if (auctionData[auctionId].minFundingThreshold > currentBidSum) {\n auctionData[auctionId].minFundingThresholdNotReached = true;\n }\n processFeesAndAuctioneerFunds(\n auctionId,\n fillVolumeOfAuctioneerOrder,\n auctioneerId,\n fullAuctionedAmount\n );\n emit AuctionCleared(\n auctionId,\n fillVolumeOfAuctioneerOrder,\n uint96(currentBidSum),\n clearingOrder\n );\n // Gas refunds\n auctionAccessManager[auctionId] = address(0);\n delete auctionAccessData[auctionId];\n auctionData[auctionId].initialAuctionOrder = bytes32(0);\n auctionData[auctionId].interimOrder = bytes32(0);\n auctionData[auctionId].interimSumBidAmount = uint256(0);\n auctionData[auctionId].minimumBiddingAmountPerOrder = uint256(0);\n }\n\n function claimFromParticipantOrder(\n uint256 auctionId,\n bytes32[] memory orders\n )\n public\n atStageFinished(auctionId)\n returns (\n uint256 sumAuctioningTokenAmount,\n uint256 sumBiddingTokenAmount\n )\n {\n for (uint256 i = 0; i < orders.length; i++) {\n // Note: we don't need to keep any information about the node since\n // no new elements need to be inserted.\n require(\n sellOrders[auctionId].remove(orders[i]),\n \"order is no longer claimable\"\n );\n }\n AuctionData memory auction = auctionData[auctionId];\n (, uint96 priceNumerator, uint96 priceDenominator) =\n auction.clearingPriceOrder.decodeOrder();\n (uint64 userId, , ) = orders[0].decodeOrder();\n bool minFundingThresholdNotReached =\n auctionData[auctionId].minFundingThresholdNotReached;\n for (uint256 i = 0; i < orders.length; i++) {\n (uint64 userIdOrder, uint96 buyAmount, uint96 sellAmount) =\n orders[i].decodeOrder();\n require(\n userIdOrder == userId,\n \"only allowed to claim for same user\"\n );\n if (minFundingThresholdNotReached) {\n //[10]\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(sellAmount);\n } else {\n //[23]\n if (orders[i] == auction.clearingPriceOrder) {\n //[25]\n sumAuctioningTokenAmount = sumAuctioningTokenAmount.add(\n auction\n .volumeClearingPriceOrder\n .mul(priceNumerator)\n .div(priceDenominator)\n );\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(\n sellAmount.sub(auction.volumeClearingPriceOrder)\n );\n } else {\n if (orders[i].smallerThan(auction.clearingPriceOrder)) {\n //[17]\n sumAuctioningTokenAmount = sumAuctioningTokenAmount.add(\n sellAmount.mul(priceNumerator).div(priceDenominator)\n );\n } else {\n //[24]\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(\n sellAmount\n );\n }\n }\n }\n emit ClaimedFromOrder(auctionId, userId, buyAmount, sellAmount);\n }\n sendOutTokens(\n auctionId,\n sumAuctioningTokenAmount,\n sumBiddingTokenAmount,\n userId\n ); //[3]\n }\n\n function processFeesAndAuctioneerFunds(\n uint256 auctionId,\n uint256 fillVolumeOfAuctioneerOrder,\n uint64 auctioneerId,\n uint96 fullAuctionedAmount\n ) internal {\n uint256 feeAmount =\n fullAuctionedAmount.mul(auctionData[auctionId].feeNumerator).div(\n FEE_DENOMINATOR\n ); //[20]\n if (auctionData[auctionId].minFundingThresholdNotReached) {\n sendOutTokens(\n auctionId,\n fullAuctionedAmount.add(feeAmount),\n 0,\n auctioneerId\n ); //[4]\n } else {\n //[11]\n (, uint96 priceNumerator, uint96 priceDenominator) =\n auctionData[auctionId].clearingPriceOrder.decodeOrder();\n uint256 unsettledAuctionTokens =\n fullAuctionedAmount.sub(fillVolumeOfAuctioneerOrder);\n uint256 auctioningTokenAmount =\n unsettledAuctionTokens.add(\n feeAmount.mul(unsettledAuctionTokens).div(\n fullAuctionedAmount\n )\n );\n uint256 biddingTokenAmount =\n fillVolumeOfAuctioneerOrder.mul(priceDenominator).div(\n priceNumerator\n );\n sendOutTokens(\n auctionId,\n auctioningTokenAmount,\n biddingTokenAmount,\n auctioneerId\n ); //[5]\n sendOutTokens(\n auctionId,\n feeAmount.mul(fillVolumeOfAuctioneerOrder).div(\n fullAuctionedAmount\n ),\n 0,\n feeReceiverUserId\n ); //[7]\n }\n }\n\n function sendOutTokens(\n uint256 auctionId,\n uint256 auctioningTokenAmount,\n uint256 biddingTokenAmount,\n uint64 userId\n ) internal {\n address userAddress = registeredUsers.getAddressAt(userId);\n if (auctioningTokenAmount > 0) {\n auctionData[auctionId].auctioningToken.safeTransfer(\n userAddress,\n auctioningTokenAmount\n );\n }\n if (biddingTokenAmount > 0) {\n auctionData[auctionId].biddingToken.safeTransfer(\n userAddress,\n biddingTokenAmount\n );\n }\n }\n\n function registerUser(address user) public returns (uint64 userId) {\n numUsers = numUsers.add(1).toUint64();\n require(\n registeredUsers.insert(numUsers, user),\n \"User already registered\"\n );\n userId = numUsers;\n emit UserRegistration(user, userId);\n }\n\n function getUserId(address user) public returns (uint64 userId) {\n if (registeredUsers.hasAddress(user)) {\n userId = registeredUsers.getId(user);\n } else {\n userId = registerUser(user);\n emit NewUser(userId, user);\n }\n }\n\n function getSecondsRemainingInBatch(uint256 auctionId)\n public\n view\n returns (uint256)\n {\n if (auctionData[auctionId].auctionEndDate < block.timestamp) {\n return 0;\n }\n return auctionData[auctionId].auctionEndDate.sub(block.timestamp);\n }\n\n function containsOrder(uint256 auctionId, bytes32 order)\n public\n view\n returns (bool)\n {\n return sellOrders[auctionId].contains(order);\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);\n\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\nimport \"../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using SafeMath for uint256;\n using Address for address;\n\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\n }\n\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n // solhint-disable-next-line max-line-length\n require((value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).add(value);\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n uint256 newAllowance = token.allowance(address(this), spender).sub(value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n if (returndata.length > 0) { // Return data is optional\n // solhint-disable-next-line max-line-length\n require(abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\n }\n }\n}\n" + }, + "contracts/libraries/IterableOrderedOrderSet.sol": { + "content": "pragma solidity >=0.6.8;\n\nimport \"@openzeppelin/contracts/math/SafeMath.sol\";\n\nlibrary IterableOrderedOrderSet {\n using SafeMath for uint96;\n using IterableOrderedOrderSet for bytes32;\n\n // represents smallest possible value for an order under comparison of fn smallerThan()\n bytes32 internal constant QUEUE_START =\n 0x0000000000000000000000000000000000000000000000000000000000000001;\n // represents highest possible value for an order under comparison of fn smallerThan()\n bytes32 internal constant QUEUE_END =\n 0xffffffffffffffffffffffffffffffffffffffff000000000000000000000001;\n\n /// The struct is used to implement a modified version of a doubly linked\n /// list with sorted elements. The list starts from QUEUE_START to\n /// QUEUE_END, and each node keeps track of its predecessor and successor.\n /// Nodes can be added or removed.\n ///\n /// `next` and `prev` have a different role. The list is supposed to be\n /// traversed with `next`. If `next` is empty, the node is not part of the\n /// list. However, `prev` might be set for elements that are not in the\n /// list, which is why it should not be used for traversing. Having a `prev`\n /// set for elements not in the list is used to keep track of the history of\n /// the position in the list of a removed element.\n struct Data {\n mapping(bytes32 => bytes32) nextMap;\n mapping(bytes32 => bytes32) prevMap;\n }\n\n struct Order {\n uint64 owner;\n uint96 buyAmount;\n uint96 sellAmount;\n }\n\n function initializeEmptyList(Data storage self) internal {\n self.nextMap[QUEUE_START] = QUEUE_END;\n self.prevMap[QUEUE_END] = QUEUE_START;\n }\n\n function isEmpty(Data storage self) internal view returns (bool) {\n return self.nextMap[QUEUE_START] == QUEUE_END;\n }\n\n function insert(\n Data storage self,\n bytes32 elementToInsert,\n bytes32 elementBeforeNewOne\n ) internal returns (bool) {\n (, , uint96 denominator) = decodeOrder(elementToInsert);\n require(denominator != uint96(0), \"Inserting zero is not supported\");\n require(\n elementToInsert != QUEUE_START && elementToInsert != QUEUE_END,\n \"Inserting element is not valid\"\n );\n if (contains(self, elementToInsert)) {\n return false;\n }\n if (\n elementBeforeNewOne != QUEUE_START &&\n self.prevMap[elementBeforeNewOne] == bytes32(0)\n ) {\n return false;\n }\n if (!elementBeforeNewOne.smallerThan(elementToInsert)) {\n return false;\n }\n\n // `elementBeforeNewOne` might have been removed during the time it\n // took to the transaction calling this function to be mined, so\n // the new order cannot be appended directly to this. We follow the\n // history of previous links backwards until we find an element in\n // the list from which to start our search.\n // Note that following the link backwards returns elements that are\n // before `elementBeforeNewOne` in sorted order.\n while (self.nextMap[elementBeforeNewOne] == bytes32(0)) {\n elementBeforeNewOne = self.prevMap[elementBeforeNewOne];\n }\n\n // `elementBeforeNewOne` belongs now to the linked list. We search the\n // largest entry that is smaller than the element to insert.\n bytes32 previous;\n bytes32 current = elementBeforeNewOne;\n do {\n previous = current;\n current = self.nextMap[current];\n } while (current.smallerThan(elementToInsert));\n // Note: previous < elementToInsert < current\n self.nextMap[previous] = elementToInsert;\n self.prevMap[current] = elementToInsert;\n self.prevMap[elementToInsert] = previous;\n self.nextMap[elementToInsert] = current;\n\n return true;\n }\n\n /// The element is removed from the linked list, but the node retains\n /// information on which predecessor it had, so that a node in the chain\n /// can be reached by following the predecessor chain of deleted elements.\n function removeKeepHistory(Data storage self, bytes32 elementToRemove)\n internal\n returns (bool)\n {\n if (!contains(self, elementToRemove)) {\n return false;\n }\n bytes32 previousElement = self.prevMap[elementToRemove];\n bytes32 nextElement = self.nextMap[elementToRemove];\n self.nextMap[previousElement] = nextElement;\n self.prevMap[nextElement] = previousElement;\n self.nextMap[elementToRemove] = bytes32(0);\n return true;\n }\n\n /// Remove an element from the chain, clearing all related storage.\n /// Note that no elements should be inserted using as a reference point a\n /// node deleted after calling `remove`, since an element in the `prev`\n /// chain might be missing.\n function remove(Data storage self, bytes32 elementToRemove)\n internal\n returns (bool)\n {\n bool result = removeKeepHistory(self, elementToRemove);\n if (result) {\n self.prevMap[elementToRemove] = bytes32(0);\n }\n return result;\n }\n\n function contains(Data storage self, bytes32 value)\n internal\n view\n returns (bool)\n {\n if (value == QUEUE_START) {\n return false;\n }\n // Note: QUEUE_END is not contained in the list since it has no\n // successor.\n return self.nextMap[value] != bytes32(0);\n }\n\n // @dev orders are ordered by\n // 1. their price - buyAmount/sellAmount\n // 2. by the sellAmount\n // 3. their userId,\n function smallerThan(bytes32 orderLeft, bytes32 orderRight)\n internal\n pure\n returns (bool)\n {\n (\n uint64 userIdLeft,\n uint96 priceNumeratorLeft,\n uint96 priceDenominatorLeft\n ) = decodeOrder(orderLeft);\n (\n uint64 userIdRight,\n uint96 priceNumeratorRight,\n uint96 priceDenominatorRight\n ) = decodeOrder(orderRight);\n\n if (\n priceNumeratorLeft.mul(priceDenominatorRight) <\n priceNumeratorRight.mul(priceDenominatorLeft)\n ) return true;\n if (\n priceNumeratorLeft.mul(priceDenominatorRight) >\n priceNumeratorRight.mul(priceDenominatorLeft)\n ) return false;\n\n if (priceNumeratorLeft < priceNumeratorRight) return true;\n if (priceNumeratorLeft > priceNumeratorRight) return false;\n require(\n userIdLeft != userIdRight,\n \"user is not allowed to place same order twice\"\n );\n if (userIdLeft < userIdRight) {\n return true;\n }\n return false;\n }\n\n function first(Data storage self) internal view returns (bytes32) {\n require(!isEmpty(self), \"Trying to get first from empty set\");\n return self.nextMap[QUEUE_START];\n }\n\n function next(Data storage self, bytes32 value)\n internal\n view\n returns (bytes32)\n {\n require(value != QUEUE_END, \"Trying to get next of last element\");\n bytes32 nextElement = self.nextMap[value];\n require(\n nextElement != bytes32(0),\n \"Trying to get next of non-existent element\"\n );\n return nextElement;\n }\n\n function decodeOrder(bytes32 _orderData)\n internal\n pure\n returns (\n uint64 userId,\n uint96 buyAmount,\n uint96 sellAmount\n )\n {\n // Note: converting to uint discards the binary digits that do not fit\n // the type.\n userId = uint64(uint256(_orderData) >> 192);\n buyAmount = uint96(uint256(_orderData) >> 96);\n sellAmount = uint96(uint256(_orderData));\n }\n\n function encodeOrder(\n uint64 userId,\n uint96 buyAmount,\n uint96 sellAmount\n ) internal pure returns (bytes32) {\n return\n bytes32(\n (uint256(userId) << 192) +\n (uint256(buyAmount) << 96) +\n uint256(sellAmount)\n );\n }\n}\n" + }, + "@openzeppelin/contracts/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a >= b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow, so we distribute\n return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);\n }\n}\n" + }, + "@openzeppelin/contracts/math/SafeMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's arithmetic operations with added overflow\n * checks.\n *\n * Arithmetic operations in Solidity wrap on overflow. This can easily result\n * in bugs, because programmers usually assume that an overflow raises an\n * error, which is the standard behavior in high level programming languages.\n * `SafeMath` restores this intuition by reverting the transaction when an\n * operation overflows.\n *\n * Using this library instead of the unchecked operations eliminates an entire\n * class of bugs, so it's recommended to use it always.\n */\nlibrary SafeMath {\n /**\n * @dev Returns the addition of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `+` operator.\n *\n * Requirements:\n *\n * - Addition cannot overflow.\n */\n function add(uint256 a, uint256 b) internal pure returns (uint256) {\n uint256 c = a + b;\n require(c >= a, \"SafeMath: addition overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b) internal pure returns (uint256) {\n return sub(a, b, \"SafeMath: subtraction overflow\");\n }\n\n /**\n * @dev Returns the subtraction of two unsigned integers, reverting with custom message on\n * overflow (when the result is negative).\n *\n * Counterpart to Solidity's `-` operator.\n *\n * Requirements:\n *\n * - Subtraction cannot overflow.\n */\n function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b <= a, errorMessage);\n uint256 c = a - b;\n\n return c;\n }\n\n /**\n * @dev Returns the multiplication of two unsigned integers, reverting on\n * overflow.\n *\n * Counterpart to Solidity's `*` operator.\n *\n * Requirements:\n *\n * - Multiplication cannot overflow.\n */\n function mul(uint256 a, uint256 b) internal pure returns (uint256) {\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\n // benefit is lost if 'b' is also tested.\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\n if (a == 0) {\n return 0;\n }\n\n uint256 c = a * b;\n require(c / a == b, \"SafeMath: multiplication overflow\");\n\n return c;\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b) internal pure returns (uint256) {\n return div(a, b, \"SafeMath: division by zero\");\n }\n\n /**\n * @dev Returns the integer division of two unsigned integers. Reverts with custom message on\n * division by zero. The result is rounded towards zero.\n *\n * Counterpart to Solidity's `/` operator. Note: this function uses a\n * `revert` opcode (which leaves remaining gas untouched) while Solidity\n * uses an invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b > 0, errorMessage);\n uint256 c = a / b;\n // assert(a == b * c + a % b); // There is no case in which this doesn't hold\n\n return c;\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b) internal pure returns (uint256) {\n return mod(a, b, \"SafeMath: modulo by zero\");\n }\n\n /**\n * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),\n * Reverts with custom message when dividing by zero.\n *\n * Counterpart to Solidity's `%` operator. This function uses a `revert`\n * opcode (which leaves remaining gas untouched) while Solidity uses an\n * invalid opcode to revert (consuming all remaining gas).\n *\n * Requirements:\n *\n * - The divisor cannot be zero.\n */\n function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {\n require(b != 0, errorMessage);\n return a % b;\n }\n}\n" + }, + "contracts/libraries/IdToAddressBiMap.sol": { + "content": "pragma solidity ^0.6.0;\n\n///////////////////////////////////////////////////////////////////////////////////////////////////////////\n// Contract does not have test coverage, as it was nearly copied from:\n// https://github.com/gnosis/solidity-data-structures/blob/master/contracts/libraries/IdToAddressBiMap.sol\n// The only change is uint16 -> uint64\n///////////////////////////////////////////////////////////////////////////////////////////////////////////\n\nlibrary IdToAddressBiMap {\n struct Data {\n mapping(uint64 => address) idToAddress;\n mapping(address => uint64) addressToId;\n }\n\n function hasId(Data storage self, uint64 id) internal view returns (bool) {\n return self.idToAddress[id + 1] != address(0);\n }\n\n function hasAddress(Data storage self, address addr)\n internal\n view\n returns (bool)\n {\n return self.addressToId[addr] != 0;\n }\n\n function getAddressAt(Data storage self, uint64 id)\n internal\n view\n returns (address)\n {\n require(hasId(self, id), \"Must have ID to get Address\");\n return self.idToAddress[id + 1];\n }\n\n function getId(Data storage self, address addr)\n internal\n view\n returns (uint64)\n {\n require(hasAddress(self, addr), \"Must have Address to get ID\");\n return self.addressToId[addr] - 1;\n }\n\n function insert(\n Data storage self,\n uint64 id,\n address addr\n ) internal returns (bool) {\n require(addr != address(0), \"Cannot insert zero address\");\n require(id != uint64(-1), \"Cannot insert max uint64\");\n // Ensure bijectivity of the mappings\n if (\n self.addressToId[addr] != 0 ||\n self.idToAddress[id + 1] != address(0)\n ) {\n return false;\n }\n self.idToAddress[id + 1] = addr;\n self.addressToId[addr] = id + 1;\n return true;\n }\n}\n" + }, + "contracts/libraries/SafeCast.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/**\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\n * checks.\n *\n * Logic was copied and modified from here: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/SafeCast.sol\n */\nlibrary SafeCast {\n function toUint96(uint256 value) internal pure returns (uint96) {\n require(value < 2**96, \"SafeCast: value doesn't fit in 96 bits\");\n return uint96(value);\n }\n\n function toUint64(uint256 value) internal pure returns (uint64) {\n require(value < 2**64, \"SafeCast: value doesn't fit in 64 bits\");\n return uint64(value);\n }\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../GSN/Context.sol\";\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor () internal {\n address msgSender = _msgSender();\n _owner = msgSender;\n emit OwnershipTransferred(address(0), msgSender);\n }\n\n /**\n * @dev Returns the address of the current owner.\n */\n function owner() public view returns (address) {\n return _owner;\n }\n\n /**\n * @dev Throws if called by any account other than the owner.\n */\n modifier onlyOwner() {\n require(_owner == _msgSender(), \"Ownable: caller is not the owner\");\n _;\n }\n\n /**\n * @dev Leaves the contract without owner. It will not be possible to call\n * `onlyOwner` functions anymore. Can only be called by the current owner.\n *\n * NOTE: Renouncing ownership will leave the contract without an owner,\n * thereby removing any functionality that is only available to the owner.\n */\n function renounceOwnership() public virtual onlyOwner {\n emit OwnershipTransferred(_owner, address(0));\n _owner = address(0);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual onlyOwner {\n require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n emit OwnershipTransferred(_owner, newOwner);\n _owner = newOwner;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.2 <0.8.0;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize, which returns 0 for contracts in\n // construction, since the code is only stored at the end of the\n // constructor execution.\n\n uint256 size;\n // solhint-disable-next-line no-inline-assembly\n assembly { size := extcodesize(account) }\n return size > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n // solhint-disable-next-line avoid-low-level-calls, avoid-call-value\n (bool success, ) = recipient.call{ value: amount }(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain`call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCall(target, data, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n require(isContract(target), \"Address: call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.call{ value: value }(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {\n require(isContract(target), \"Address: static call to non-contract\");\n\n // solhint-disable-next-line avoid-low-level-calls\n (bool success, bytes memory returndata) = target.staticcall(data);\n return _verifyCallResult(success, returndata, errorMessage);\n }\n\n function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {\n if (success) {\n return returndata;\n } else {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n\n // solhint-disable-next-line no-inline-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n }\n}\n" + }, + "@openzeppelin/contracts/GSN/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\n/*\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with GSN meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address payable) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes memory) {\n this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691\n return msg.data;\n }\n}\n" + }, + "contracts/wrappers/DepositAndPlaceOrder.sol": { + "content": "pragma solidity >=0.6.8;\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"../EasyAuction.sol\";\nimport \"../interfaces/IWETH.sol\";\n\ncontract DepositAndPlaceOrder {\n EasyAuction public immutable easyAuction;\n IWETH public immutable nativeTokenWrapper;\n\n constructor(address easyAuctionAddress, address _nativeTokenWrapper)\n public\n {\n nativeTokenWrapper = IWETH(_nativeTokenWrapper);\n easyAuction = EasyAuction(easyAuctionAddress);\n IERC20(_nativeTokenWrapper).approve(easyAuctionAddress, uint256(-1));\n }\n\n function depositAndPlaceOrder(\n uint256 auctionId,\n uint96[] memory _minBuyAmounts,\n bytes32[] memory _prevSellOrders,\n bytes calldata allowListCallData\n ) external payable returns (uint64 userId) {\n uint96[] memory sellAmounts = new uint96[](1);\n require(msg.value < 2**96, \"too much value sent\");\n nativeTokenWrapper.deposit{value: msg.value}();\n sellAmounts[0] = uint96(msg.value);\n return\n easyAuction.placeSellOrdersOnBehalf(\n auctionId,\n _minBuyAmounts,\n sellAmounts,\n _prevSellOrders,\n allowListCallData,\n msg.sender\n );\n }\n}\n" + }, + "contracts/interfaces/IWETH.sol": { + "content": "pragma solidity >=0.6.0;\n\ninterface IWETH {\n function deposit() external payable;\n\n function transfer(address to, uint256 value) external returns (bool);\n\n function withdraw(uint256) external;\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.6.0 <0.8.0;\n\nimport \"../../GSN/Context.sol\";\nimport \"./IERC20.sol\";\nimport \"../../math/SafeMath.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\n * to implement supply mechanisms].\n *\n * We have followed general OpenZeppelin guidelines: functions revert instead\n * of returning `false` on failure. This behavior is nonetheless conventional\n * and does not conflict with the expectations of ERC20 applications.\n *\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\n * This allows applications to reconstruct the allowance for all accounts just\n * by listening to said events. Other implementations of the EIP may not emit\n * these events, as it isn't required by the specification.\n *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20 {\n using SafeMath for uint256;\n\n mapping (address => uint256) private _balances;\n\n mapping (address => mapping (address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n uint8 private _decimals;\n\n /**\n * @dev Sets the values for {name} and {symbol}, initializes {decimals} with\n * a default value of 18.\n *\n * To select a different value for {decimals}, use {_setupDecimals}.\n *\n * All three of these values are immutable: they can only be set once during\n * construction.\n */\n constructor (string memory name_, string memory symbol_) public {\n _name = name_;\n _symbol = symbol_;\n _decimals = 18;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5,05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is\n * called.\n *\n * NOTE: This information is only used for _display_ purposes: it in\n * no way affects any of the arithmetic of the contract, including\n * {IERC20-balanceOf} and {IERC20-transfer}.\n */\n function decimals() public view returns (uint8) {\n return _decimals;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `recipient` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(_msgSender(), recipient, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\n _approve(_msgSender(), spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * Requirements:\n *\n * - `sender` and `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n * - the caller must have allowance for ``sender``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {\n _transfer(sender, recipient, amount);\n _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, \"ERC20: transfer amount exceeds allowance\"));\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, \"ERC20: decreased allowance below zero\"));\n return true;\n }\n\n /**\n * @dev Moves tokens `amount` from `sender` to `recipient`.\n *\n * This is internal function is equivalent to {transfer}, and can be used to\n * e.g. implement automatic token fees, slashing mechanisms, etc.\n *\n * Emits a {Transfer} event.\n *\n * Requirements:\n *\n * - `sender` cannot be the zero address.\n * - `recipient` cannot be the zero address.\n * - `sender` must have a balance of at least `amount`.\n */\n function _transfer(address sender, address recipient, uint256 amount) internal virtual {\n require(sender != address(0), \"ERC20: transfer from the zero address\");\n require(recipient != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(sender, recipient, amount);\n\n _balances[sender] = _balances[sender].sub(amount, \"ERC20: transfer amount exceeds balance\");\n _balances[recipient] = _balances[recipient].add(amount);\n emit Transfer(sender, recipient, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply = _totalSupply.add(amount);\n _balances[account] = _balances[account].add(amount);\n emit Transfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n _balances[account] = _balances[account].sub(amount, \"ERC20: burn amount exceeds balance\");\n _totalSupply = _totalSupply.sub(amount);\n emit Transfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Sets {decimals} to a value other than the default one of 18.\n *\n * WARNING: This function should only be called from the constructor. Most\n * applications that interact with token contracts will not expect\n * {decimals} to ever change, and may work incorrectly if it does.\n */\n function _setupDecimals(uint8 decimals_) internal {\n _decimals = decimals_;\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be to transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }\n}\n" + }, + "contracts/test/IterableOrderedOrderSetWrapper.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-or-newer\npragma solidity ^0.6.0;\nimport \"../libraries/IterableOrderedOrderSet.sol\";\n\ncontract IterableOrderedOrderSetWrapper {\n using IterableOrderedOrderSet for IterableOrderedOrderSet.Data;\n\n IterableOrderedOrderSet.Data internal data;\n\n function initializeEmptyList() public {\n data.initializeEmptyList();\n }\n\n function insert(bytes32 value) public returns (bool) {\n return data.insert(value, IterableOrderedOrderSet.QUEUE_START);\n }\n\n function insertAt(bytes32 value, bytes32 at) public returns (bool) {\n return data.insert(value, at);\n }\n\n function remove(bytes32 value) public returns (bool) {\n return data.remove(value);\n }\n\n function removeKeepHistory(bytes32 value) public returns (bool) {\n return data.removeKeepHistory(value);\n }\n\n function contains(bytes32 value) public view returns (bool) {\n return data.contains(value);\n }\n\n function isEmpty() public view returns (bool) {\n return data.isEmpty();\n }\n\n function first() public view returns (bytes32) {\n return data.first();\n }\n\n function next(bytes32 value) public view returns (bytes32) {\n return data.next(value);\n }\n\n function nextMap(bytes32 value) public view returns (bytes32) {\n return data.nextMap[value];\n }\n\n function prevMap(bytes32 value) public view returns (bytes32) {\n return data.prevMap[value];\n }\n\n function decodeOrder(bytes32 value)\n public\n pure\n returns (\n uint64,\n uint96,\n uint96\n )\n {\n return IterableOrderedOrderSet.decodeOrder(value);\n }\n\n function encodeOrder(\n uint64 userId,\n uint96 sellAmount,\n uint96 buyAmount\n ) public pure returns (bytes32) {\n return\n IterableOrderedOrderSet.encodeOrder(userId, sellAmount, buyAmount);\n }\n\n function smallerThan(bytes32 orderLeft, bytes32 orderRight)\n public\n pure\n returns (bool)\n {\n return IterableOrderedOrderSet.smallerThan(orderLeft, orderRight);\n }\n}\n" + }, + "contracts/test/ERC20Mintable.sol": { + "content": "pragma solidity >=0.6.8;\n\nimport \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\ncontract ERC20Mintable is ERC20 {\n constructor(string memory name, string memory symbol)\n public\n ERC20(symbol, name)\n {}\n\n function mint(address account, uint256 amount) public {\n _mint(account, amount);\n }\n}\n" + }, + "contracts/test/StateChangingAllowListVerifier.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-or-later\npragma solidity >=0.6.8;\nimport \"../interfaces/AllowListVerifier.sol\";\n\ncontract StateChangingAllowListVerifier {\n bytes32 public test = bytes32(0);\n\n function isAllowed(\n address user,\n uint256 auctionId,\n bytes calldata callData\n ) external returns (bytes4) {\n test = keccak256(abi.encode(user, auctionId, callData));\n return AllowListVerifierHelper.MAGICVALUE;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": false, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/hardhat.config.ts b/hardhat.config.ts index 9b9502c..5c38d51 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -151,6 +151,13 @@ export default { ) : "auto", }, + binancesmartchaintestnet: { + ...sharedNetworkConfig, + url: "https://data-seed-prebsc-1-s1.binance.org:8545/", + gasPrice: GAS_PRICE_GWEI + ? utils.parseUnits(GAS_PRICE_GWEI.toString(), "gwei").toString() + : "auto", + }, fuji: { ...sharedNetworkConfig, chainId: 43113, diff --git a/src/tasks/utils.ts b/src/tasks/utils.ts index b4049b3..91b5be7 100644 --- a/src/tasks/utils.ts +++ b/src/tasks/utils.ts @@ -75,6 +75,8 @@ export async function getWETH9Address( weth9Address = "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270"; } else if (chainId == 56) { weth9Address = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; + } else if (chainId == 97) { + weth9Address = "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd"; } else if (chainId == 100) { weth9Address = "0xe91D153E0b41518A2Ce8Dd3D7944Fa863463a97d"; } else if (chainId == 43113) {