JustPaste.it

AllowListOffChainManaged.json

{ "address": "0x0F4648d997e486cE06577d6Ee2FecBcA84b834F4", "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" } ], "transactionHash": "0x9be0d0f472e3a41c1fb314624965fefbdeb0c5ebe3671c59191a794b68265f10", "receipt": { "to": "0x4e59b44847b379578588920cA78FbF26c0B4956C", "from": "0x8AB8530AEe3E5eD7Ecf5D7CA69c903Ed04595094", "contractAddress": null, "transactionIndex": 0, "gasUsed": "383192", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "blockHash": "0xaf3e0b2ce97a0605be98ce6617bdc7e842bd3d1ed57e5605a5a1d4e2afd015a9", "transactionHash": "0x9be0d0f472e3a41c1fb314624965fefbdeb0c5ebe3671c59191a794b68265f10", "logs": [], "blockNumber": 15264432, "cumulativeGasUsed": "383192", "status": 1, "byzantium": true }, "args": [], "solcInputHash": "ad868d512eafc63430765fc273a2c47b", "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;\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/token/ERC20/SafeERC20.sol\\\";\\r\\nimport \\\"./libraries/IterableOrderedOrderSet.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/math/Math.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\r\\nimport \\\"./libraries/IdToAddressBiMap.sol\\\";\\r\\nimport \\\"./libraries/SafeCast.sol\\\";\\r\\nimport \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\r\\nimport \\\"./interfaces/AllowListVerifier.sol\\\";\\r\\n\\r\\ncontract EasyAuction is Ownable {\\r\\n using SafeERC20 for IERC20;\\r\\n using SafeMath for uint64;\\r\\n using SafeMath for uint96;\\r\\n using SafeMath for uint256;\\r\\n using SafeCast for uint256;\\r\\n using IterableOrderedOrderSet for IterableOrderedOrderSet.Data;\\r\\n using IterableOrderedOrderSet for bytes32;\\r\\n using IdToAddressBiMap for IdToAddressBiMap.Data;\\r\\n\\r\\n modifier atStageOrderPlacement(uint256 auctionId) {\\r\\n require(\\r\\n block.timestamp < auctionData[auctionId].auctionEndDate,\\r\\n \\\"no longer in order placement phase\\\"\\r\\n );\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier atStageOrderPlacementAndCancelation(uint256 auctionId) {\\r\\n require(\\r\\n block.timestamp < auctionData[auctionId].orderCancellationEndDate,\\r\\n \\\"no longer in order placement and cancelation phase\\\"\\r\\n );\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier atStageSolutionSubmission(uint256 auctionId) {\\r\\n {\\r\\n uint256 auctionEndDate = auctionData[auctionId].auctionEndDate;\\r\\n require(\\r\\n auctionEndDate != 0 &&\\r\\n block.timestamp >= auctionEndDate &&\\r\\n auctionData[auctionId].clearingPriceOrder == bytes32(0),\\r\\n \\\"Auction not in solution submission phase\\\"\\r\\n );\\r\\n }\\r\\n _;\\r\\n }\\r\\n\\r\\n modifier atStageFinished(uint256 auctionId) {\\r\\n require(\\r\\n auctionData[auctionId].clearingPriceOrder != bytes32(0),\\r\\n \\\"Auction not yet finished\\\"\\r\\n );\\r\\n _;\\r\\n }\\r\\n\\r\\n event NewSellOrder(\\r\\n uint256 indexed auctionId,\\r\\n uint64 indexed userId,\\r\\n uint96 buyAmount,\\r\\n uint96 sellAmount\\r\\n );\\r\\n event CancellationSellOrder(\\r\\n uint256 indexed auctionId,\\r\\n uint64 indexed userId,\\r\\n uint96 buyAmount,\\r\\n uint96 sellAmount\\r\\n );\\r\\n event ClaimedFromOrder(\\r\\n uint256 indexed auctionId,\\r\\n uint64 indexed userId,\\r\\n uint96 buyAmount,\\r\\n uint96 sellAmount\\r\\n );\\r\\n event NewUser(uint64 indexed userId, address indexed userAddress);\\r\\n event NewAuction(\\r\\n uint256 indexed auctionId,\\r\\n IERC20 indexed _auctioningToken,\\r\\n IERC20 indexed _biddingToken,\\r\\n uint256 orderCancellationEndDate,\\r\\n uint256 auctionEndDate,\\r\\n uint64 userId,\\r\\n uint96 _auctionedSellAmount,\\r\\n uint96 _minBuyAmount,\\r\\n uint256 minimumBiddingAmountPerOrder,\\r\\n uint256 minFundingThreshold,\\r\\n address allowListContract,\\r\\n bytes allowListData\\r\\n );\\r\\n event AuctionCleared(\\r\\n uint256 indexed auctionId,\\r\\n uint96 soldAuctioningTokens,\\r\\n uint96 soldBiddingTokens,\\r\\n bytes32 clearingPriceOrder\\r\\n );\\r\\n event UserRegistration(address indexed user, uint64 userId);\\r\\n\\r\\n struct AuctionData {\\r\\n IERC20 auctioningToken;\\r\\n IERC20 biddingToken;\\r\\n uint256 orderCancellationEndDate;\\r\\n uint256 auctionEndDate;\\r\\n bytes32 initialAuctionOrder;\\r\\n uint256 minimumBiddingAmountPerOrder;\\r\\n uint256 interimSumBidAmount;\\r\\n bytes32 interimOrder;\\r\\n bytes32 clearingPriceOrder;\\r\\n uint96 volumeClearingPriceOrder;\\r\\n bool minFundingThresholdNotReached;\\r\\n bool isAtomicClosureAllowed;\\r\\n uint256 feeNumerator;\\r\\n uint256 minFundingThreshold;\\r\\n }\\r\\n mapping(uint256 => IterableOrderedOrderSet.Data) internal sellOrders;\\r\\n mapping(uint256 => AuctionData) public auctionData;\\r\\n mapping(uint256 => address) public auctionAccessManager;\\r\\n mapping(uint256 => bytes) public auctionAccessData;\\r\\n\\r\\n IdToAddressBiMap.Data private registeredUsers;\\r\\n uint64 public numUsers;\\r\\n uint256 public auctionCounter;\\r\\n\\r\\n constructor() public Ownable() {}\\r\\n\\r\\n uint256 public feeNumerator = 0;\\r\\n uint256 public constant FEE_DENOMINATOR = 1000;\\r\\n uint64 public feeReceiverUserId = 1;\\r\\n\\r\\n function setFeeParameters(\\r\\n uint256 newFeeNumerator,\\r\\n address newfeeReceiverAddress\\r\\n ) public onlyOwner() {\\r\\n require(\\r\\n newFeeNumerator <= 15,\\r\\n \\\"Fee is not allowed to be set higher than 1.5%\\\"\\r\\n );\\r\\n // caution: for currently running auctions, the feeReceiverUserId is changing as well.\\r\\n feeReceiverUserId = getUserId(newfeeReceiverAddress);\\r\\n feeNumerator = newFeeNumerator;\\r\\n }\\r\\n\\r\\n // @dev: function to intiate a new auction\\r\\n // Warning: In case the auction is expected to raise more than\\r\\n // 2^96 units of the biddingToken, don't start the auction, as\\r\\n // it will not be settlable. This corresponds to about 79\\r\\n // billion DAI.\\r\\n //\\r\\n // Prices between biddingToken and auctioningToken are expressed by a\\r\\n // fraction whose components are stored as uint96.\\r\\n function initiateAuction(\\r\\n IERC20 _auctioningToken,\\r\\n IERC20 _biddingToken,\\r\\n uint256 orderCancellationEndDate,\\r\\n uint256 auctionEndDate,\\r\\n uint96 _auctionedSellAmount,\\r\\n uint96 _minBuyAmount,\\r\\n uint256 minimumBiddingAmountPerOrder,\\r\\n uint256 minFundingThreshold,\\r\\n bool isAtomicClosureAllowed,\\r\\n address accessManagerContract,\\r\\n bytes memory accessManagerContractData\\r\\n ) public returns (uint256) {\\r\\n // withdraws sellAmount + fees\\r\\n _auctioningToken.safeTransferFrom(\\r\\n msg.sender,\\r\\n address(this),\\r\\n _auctionedSellAmount.mul(FEE_DENOMINATOR.add(feeNumerator)).div(\\r\\n FEE_DENOMINATOR\\r\\n ) //[0]\\r\\n );\\r\\n require(_auctionedSellAmount > 0, \\\"cannot auction zero tokens\\\");\\r\\n require(_minBuyAmount > 0, \\\"tokens cannot be auctioned for free\\\");\\r\\n require(\\r\\n minimumBiddingAmountPerOrder > 0,\\r\\n \\\"minimumBiddingAmountPerOrder is not allowed to be zero\\\"\\r\\n );\\r\\n require(\\r\\n orderCancellationEndDate <= auctionEndDate,\\r\\n \\\"time periods are not configured correctly\\\"\\r\\n );\\r\\n require(\\r\\n auctionEndDate > block.timestamp,\\r\\n \\\"auction end date must be in the future\\\"\\r\\n );\\r\\n auctionCounter = auctionCounter.add(1);\\r\\n sellOrders[auctionCounter].initializeEmptyList();\\r\\n uint64 userId = getUserId(msg.sender);\\r\\n auctionData[auctionCounter] = AuctionData(\\r\\n _auctioningToken,\\r\\n _biddingToken,\\r\\n orderCancellationEndDate,\\r\\n auctionEndDate,\\r\\n IterableOrderedOrderSet.encodeOrder(\\r\\n userId,\\r\\n _minBuyAmount,\\r\\n _auctionedSellAmount\\r\\n ),\\r\\n minimumBiddingAmountPerOrder,\\r\\n 0,\\r\\n IterableOrderedOrderSet.QUEUE_START,\\r\\n bytes32(0),\\r\\n 0,\\r\\n false,\\r\\n isAtomicClosureAllowed,\\r\\n feeNumerator,\\r\\n minFundingThreshold\\r\\n );\\r\\n auctionAccessManager[auctionCounter] = accessManagerContract;\\r\\n auctionAccessData[auctionCounter] = accessManagerContractData;\\r\\n emit NewAuction(\\r\\n auctionCounter,\\r\\n _auctioningToken,\\r\\n _biddingToken,\\r\\n orderCancellationEndDate,\\r\\n auctionEndDate,\\r\\n userId,\\r\\n _auctionedSellAmount,\\r\\n _minBuyAmount,\\r\\n minimumBiddingAmountPerOrder,\\r\\n minFundingThreshold,\\r\\n accessManagerContract,\\r\\n accessManagerContractData\\r\\n );\\r\\n return auctionCounter;\\r\\n }\\r\\n\\r\\n function placeSellOrders(\\r\\n uint256 auctionId,\\r\\n uint96[] memory _minBuyAmounts,\\r\\n uint96[] memory _sellAmounts,\\r\\n bytes32[] memory _prevSellOrders,\\r\\n bytes calldata allowListCallData\\r\\n ) external atStageOrderPlacement(auctionId) returns (uint64 userId) {\\r\\n return\\r\\n _placeSellOrders(\\r\\n auctionId,\\r\\n _minBuyAmounts,\\r\\n _sellAmounts,\\r\\n _prevSellOrders,\\r\\n allowListCallData,\\r\\n msg.sender\\r\\n );\\r\\n }\\r\\n\\r\\n function placeSellOrdersOnBehalf(\\r\\n uint256 auctionId,\\r\\n uint96[] memory _minBuyAmounts,\\r\\n uint96[] memory _sellAmounts,\\r\\n bytes32[] memory _prevSellOrders,\\r\\n bytes calldata allowListCallData,\\r\\n address orderSubmitter\\r\\n ) external atStageOrderPlacement(auctionId) returns (uint64 userId) {\\r\\n return\\r\\n _placeSellOrders(\\r\\n auctionId,\\r\\n _minBuyAmounts,\\r\\n _sellAmounts,\\r\\n _prevSellOrders,\\r\\n allowListCallData,\\r\\n orderSubmitter\\r\\n );\\r\\n }\\r\\n\\r\\n function _placeSellOrders(\\r\\n uint256 auctionId,\\r\\n uint96[] memory _minBuyAmounts,\\r\\n uint96[] memory _sellAmounts,\\r\\n bytes32[] memory _prevSellOrders,\\r\\n bytes calldata allowListCallData,\\r\\n address orderSubmitter\\r\\n ) internal returns (uint64 userId) {\\r\\n {\\r\\n address allowListManger = auctionAccessManager[auctionId];\\r\\n if (allowListManger != address(0)) {\\r\\n require(\\r\\n AllowListVerifier(allowListManger).isAllowed(\\r\\n orderSubmitter,\\r\\n auctionId,\\r\\n allowListCallData\\r\\n ) == AllowListVerifierHelper.MAGICVALUE,\\r\\n \\\"user not allowed to place order\\\"\\r\\n );\\r\\n }\\r\\n }\\r\\n {\\r\\n (\\r\\n ,\\r\\n uint96 buyAmountOfInitialAuctionOrder,\\r\\n uint96 sellAmountOfInitialAuctionOrder\\r\\n ) = auctionData[auctionId].initialAuctionOrder.decodeOrder();\\r\\n for (uint256 i = 0; i < _minBuyAmounts.length; i++) {\\r\\n require(\\r\\n _minBuyAmounts[i].mul(buyAmountOfInitialAuctionOrder) <\\r\\n sellAmountOfInitialAuctionOrder.mul(_sellAmounts[i]),\\r\\n \\\"limit price not better than mimimal offer\\\"\\r\\n );\\r\\n }\\r\\n }\\r\\n uint256 sumOfSellAmounts = 0;\\r\\n userId = getUserId(orderSubmitter);\\r\\n uint256 minimumBiddingAmountPerOrder =\\r\\n auctionData[auctionId].minimumBiddingAmountPerOrder;\\r\\n for (uint256 i = 0; i < _minBuyAmounts.length; i++) {\\r\\n require(\\r\\n _minBuyAmounts[i] > 0,\\r\\n \\\"_minBuyAmounts must be greater than 0\\\"\\r\\n );\\r\\n // orders should have a minimum bid size in order to limit the gas\\r\\n // required to compute the final price of the auction.\\r\\n require(\\r\\n _sellAmounts[i] > minimumBiddingAmountPerOrder,\\r\\n \\\"order too small\\\"\\r\\n );\\r\\n if (\\r\\n sellOrders[auctionId].insert(\\r\\n IterableOrderedOrderSet.encodeOrder(\\r\\n userId,\\r\\n _minBuyAmounts[i],\\r\\n _sellAmounts[i]\\r\\n ),\\r\\n _prevSellOrders[i]\\r\\n )\\r\\n ) {\\r\\n sumOfSellAmounts = sumOfSellAmounts.add(_sellAmounts[i]);\\r\\n emit NewSellOrder(\\r\\n auctionId,\\r\\n userId,\\r\\n _minBuyAmounts[i],\\r\\n _sellAmounts[i]\\r\\n );\\r\\n }\\r\\n }\\r\\n auctionData[auctionId].biddingToken.safeTransferFrom(\\r\\n msg.sender,\\r\\n address(this),\\r\\n sumOfSellAmounts\\r\\n ); //[1]\\r\\n }\\r\\n\\r\\n function cancelSellOrders(uint256 auctionId, bytes32[] memory _sellOrders)\\r\\n public\\r\\n atStageOrderPlacementAndCancelation(auctionId)\\r\\n {\\r\\n uint64 userId = getUserId(msg.sender);\\r\\n uint256 claimableAmount = 0;\\r\\n for (uint256 i = 0; i < _sellOrders.length; i++) {\\r\\n // Note: we keep the back pointer of the deleted element so that\\r\\n // it can be used as a reference point to insert a new node.\\r\\n bool success =\\r\\n sellOrders[auctionId].removeKeepHistory(_sellOrders[i]);\\r\\n if (success) {\\r\\n (\\r\\n uint64 userIdOfIter,\\r\\n uint96 buyAmountOfIter,\\r\\n uint96 sellAmountOfIter\\r\\n ) = _sellOrders[i].decodeOrder();\\r\\n require(\\r\\n userIdOfIter == userId,\\r\\n \\\"Only the user can cancel his orders\\\"\\r\\n );\\r\\n claimableAmount = claimableAmount.add(sellAmountOfIter);\\r\\n emit CancellationSellOrder(\\r\\n auctionId,\\r\\n userId,\\r\\n buyAmountOfIter,\\r\\n sellAmountOfIter\\r\\n );\\r\\n }\\r\\n }\\r\\n auctionData[auctionId].biddingToken.safeTransfer(\\r\\n msg.sender,\\r\\n claimableAmount\\r\\n ); //[2]\\r\\n }\\r\\n\\r\\n function precalculateSellAmountSum(\\r\\n uint256 auctionId,\\r\\n uint256 iterationSteps\\r\\n ) public atStageSolutionSubmission(auctionId) {\\r\\n (, , uint96 auctioneerSellAmount) =\\r\\n auctionData[auctionId].initialAuctionOrder.decodeOrder();\\r\\n uint256 sumBidAmount = auctionData[auctionId].interimSumBidAmount;\\r\\n bytes32 iterOrder = auctionData[auctionId].interimOrder;\\r\\n\\r\\n for (uint256 i = 0; i < iterationSteps; i++) {\\r\\n iterOrder = sellOrders[auctionId].next(iterOrder);\\r\\n (, , uint96 sellAmountOfIter) = iterOrder.decodeOrder();\\r\\n sumBidAmount = sumBidAmount.add(sellAmountOfIter);\\r\\n }\\r\\n\\r\\n require(\\r\\n iterOrder != IterableOrderedOrderSet.QUEUE_END,\\r\\n \\\"reached end of order list\\\"\\r\\n );\\r\\n\\r\\n // it is checked that not too many iteration steps were taken:\\r\\n // require that the sum of SellAmounts times the price of the last order\\r\\n // is not more than initially sold amount\\r\\n (, uint96 buyAmountOfIter, uint96 sellAmountOfIter) =\\r\\n iterOrder.decodeOrder();\\r\\n require(\\r\\n sumBidAmount.mul(buyAmountOfIter) <\\r\\n auctioneerSellAmount.mul(sellAmountOfIter),\\r\\n \\\"too many orders summed up\\\"\\r\\n );\\r\\n\\r\\n auctionData[auctionId].interimSumBidAmount = sumBidAmount;\\r\\n auctionData[auctionId].interimOrder = iterOrder;\\r\\n }\\r\\n\\r\\n function settleAuctionAtomically(\\r\\n uint256 auctionId,\\r\\n uint96[] memory _minBuyAmount,\\r\\n uint96[] memory _sellAmount,\\r\\n bytes32[] memory _prevSellOrder,\\r\\n bytes calldata allowListCallData\\r\\n ) public atStageSolutionSubmission(auctionId) {\\r\\n require(\\r\\n auctionData[auctionId].isAtomicClosureAllowed,\\r\\n \\\"not allowed to settle auction atomically\\\"\\r\\n );\\r\\n require(\\r\\n _minBuyAmount.length == 1 && _sellAmount.length == 1,\\r\\n \\\"Only one order can be placed atomically\\\"\\r\\n );\\r\\n uint64 userId = getUserId(msg.sender);\\r\\n require(\\r\\n auctionData[auctionId].interimOrder.smallerThan(\\r\\n IterableOrderedOrderSet.encodeOrder(\\r\\n userId,\\r\\n _minBuyAmount[0],\\r\\n _sellAmount[0]\\r\\n )\\r\\n ),\\r\\n \\\"precalculateSellAmountSum is already too advanced\\\"\\r\\n );\\r\\n _placeSellOrders(\\r\\n auctionId,\\r\\n _minBuyAmount,\\r\\n _sellAmount,\\r\\n _prevSellOrder,\\r\\n allowListCallData,\\r\\n msg.sender\\r\\n );\\r\\n settleAuction(auctionId);\\r\\n }\\r\\n\\r\\n // @dev function settling the auction and calculating the price\\r\\n function settleAuction(uint256 auctionId)\\r\\n public\\r\\n atStageSolutionSubmission(auctionId)\\r\\n returns (bytes32 clearingOrder)\\r\\n {\\r\\n (\\r\\n uint64 auctioneerId,\\r\\n uint96 minAuctionedBuyAmount,\\r\\n uint96 fullAuctionedAmount\\r\\n ) = auctionData[auctionId].initialAuctionOrder.decodeOrder();\\r\\n\\r\\n uint256 currentBidSum = auctionData[auctionId].interimSumBidAmount;\\r\\n bytes32 currentOrder = auctionData[auctionId].interimOrder;\\r\\n uint256 buyAmountOfIter;\\r\\n uint256 sellAmountOfIter;\\r\\n uint96 fillVolumeOfAuctioneerOrder = fullAuctionedAmount;\\r\\n // Sum order up, until fullAuctionedAmount is fully bought or queue end is reached\\r\\n do {\\r\\n bytes32 nextOrder = sellOrders[auctionId].next(currentOrder);\\r\\n if (nextOrder == IterableOrderedOrderSet.QUEUE_END) {\\r\\n break;\\r\\n }\\r\\n currentOrder = nextOrder;\\r\\n (, buyAmountOfIter, sellAmountOfIter) = currentOrder.decodeOrder();\\r\\n currentBidSum = currentBidSum.add(sellAmountOfIter);\\r\\n } while (\\r\\n currentBidSum.mul(buyAmountOfIter) <\\r\\n fullAuctionedAmount.mul(sellAmountOfIter)\\r\\n );\\r\\n\\r\\n if (\\r\\n currentBidSum > 0 &&\\r\\n currentBidSum.mul(buyAmountOfIter) >=\\r\\n fullAuctionedAmount.mul(sellAmountOfIter)\\r\\n ) {\\r\\n // All considered/summed orders are sufficient to close the auction fully\\r\\n // at price between current and previous orders.\\r\\n uint256 uncoveredBids =\\r\\n currentBidSum.sub(\\r\\n fullAuctionedAmount.mul(sellAmountOfIter).div(\\r\\n buyAmountOfIter\\r\\n )\\r\\n );\\r\\n\\r\\n if (sellAmountOfIter >= uncoveredBids) {\\r\\n //[13]\\r\\n // Auction fully filled via partial match of currentOrder\\r\\n uint256 sellAmountClearingOrder =\\r\\n sellAmountOfIter.sub(uncoveredBids);\\r\\n auctionData[auctionId]\\r\\n .volumeClearingPriceOrder = sellAmountClearingOrder\\r\\n .toUint96();\\r\\n currentBidSum = currentBidSum.sub(uncoveredBids);\\r\\n clearingOrder = currentOrder;\\r\\n } else {\\r\\n //[14]\\r\\n // Auction fully filled via price strictly between currentOrder and the order\\r\\n // immediately before. For a proof, see the security-considerations.md\\r\\n currentBidSum = currentBidSum.sub(sellAmountOfIter);\\r\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\r\\n 0,\\r\\n fullAuctionedAmount,\\r\\n currentBidSum.toUint96()\\r\\n );\\r\\n }\\r\\n } else {\\r\\n // All considered/summed orders are not sufficient to close the auction fully at price of last order //[18]\\r\\n // Either a higher price must be used or auction is only partially filled\\r\\n\\r\\n if (currentBidSum > minAuctionedBuyAmount) {\\r\\n //[15]\\r\\n // Price higher than last order would fill the auction\\r\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\r\\n 0,\\r\\n fullAuctionedAmount,\\r\\n currentBidSum.toUint96()\\r\\n );\\r\\n } else {\\r\\n //[16]\\r\\n // Even at the initial auction price, the auction is partially filled\\r\\n clearingOrder = IterableOrderedOrderSet.encodeOrder(\\r\\n 0,\\r\\n fullAuctionedAmount,\\r\\n minAuctionedBuyAmount\\r\\n );\\r\\n fillVolumeOfAuctioneerOrder = currentBidSum\\r\\n .mul(fullAuctionedAmount)\\r\\n .div(minAuctionedBuyAmount)\\r\\n .toUint96();\\r\\n }\\r\\n }\\r\\n auctionData[auctionId].clearingPriceOrder = clearingOrder;\\r\\n\\r\\n if (auctionData[auctionId].minFundingThreshold > currentBidSum) {\\r\\n auctionData[auctionId].minFundingThresholdNotReached = true;\\r\\n }\\r\\n processFeesAndAuctioneerFunds(\\r\\n auctionId,\\r\\n fillVolumeOfAuctioneerOrder,\\r\\n auctioneerId,\\r\\n fullAuctionedAmount\\r\\n );\\r\\n emit AuctionCleared(\\r\\n auctionId,\\r\\n fillVolumeOfAuctioneerOrder,\\r\\n uint96(currentBidSum),\\r\\n clearingOrder\\r\\n );\\r\\n // Gas refunds\\r\\n auctionAccessManager[auctionId] = address(0);\\r\\n delete auctionAccessData[auctionId];\\r\\n auctionData[auctionId].initialAuctionOrder = bytes32(0);\\r\\n auctionData[auctionId].interimOrder = bytes32(0);\\r\\n auctionData[auctionId].interimSumBidAmount = uint256(0);\\r\\n auctionData[auctionId].minimumBiddingAmountPerOrder = uint256(0);\\r\\n }\\r\\n\\r\\n function claimFromParticipantOrder(\\r\\n uint256 auctionId,\\r\\n bytes32[] memory orders\\r\\n )\\r\\n public\\r\\n atStageFinished(auctionId)\\r\\n returns (\\r\\n uint256 sumAuctioningTokenAmount,\\r\\n uint256 sumBiddingTokenAmount\\r\\n )\\r\\n {\\r\\n for (uint256 i = 0; i < orders.length; i++) {\\r\\n // Note: we don't need to keep any information about the node since\\r\\n // no new elements need to be inserted.\\r\\n require(\\r\\n sellOrders[auctionId].remove(orders[i]),\\r\\n \\\"order is no longer claimable\\\"\\r\\n );\\r\\n }\\r\\n AuctionData memory auction = auctionData[auctionId];\\r\\n (, uint96 priceNumerator, uint96 priceDenominator) =\\r\\n auction.clearingPriceOrder.decodeOrder();\\r\\n (uint64 userId, , ) = orders[0].decodeOrder();\\r\\n bool minFundingThresholdNotReached =\\r\\n auctionData[auctionId].minFundingThresholdNotReached;\\r\\n for (uint256 i = 0; i < orders.length; i++) {\\r\\n (uint64 userIdOrder, uint96 buyAmount, uint96 sellAmount) =\\r\\n orders[i].decodeOrder();\\r\\n require(\\r\\n userIdOrder == userId,\\r\\n \\\"only allowed to claim for same user\\\"\\r\\n );\\r\\n if (minFundingThresholdNotReached) {\\r\\n //[10]\\r\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(sellAmount);\\r\\n } else {\\r\\n //[23]\\r\\n if (orders[i] == auction.clearingPriceOrder) {\\r\\n //[25]\\r\\n sumAuctioningTokenAmount = sumAuctioningTokenAmount.add(\\r\\n auction\\r\\n .volumeClearingPriceOrder\\r\\n .mul(priceNumerator)\\r\\n .div(priceDenominator)\\r\\n );\\r\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(\\r\\n sellAmount.sub(auction.volumeClearingPriceOrder)\\r\\n );\\r\\n } else {\\r\\n if (orders[i].smallerThan(auction.clearingPriceOrder)) {\\r\\n //[17]\\r\\n sumAuctioningTokenAmount = sumAuctioningTokenAmount.add(\\r\\n sellAmount.mul(priceNumerator).div(priceDenominator)\\r\\n );\\r\\n } else {\\r\\n //[24]\\r\\n sumBiddingTokenAmount = sumBiddingTokenAmount.add(\\r\\n sellAmount\\r\\n );\\r\\n }\\r\\n }\\r\\n }\\r\\n emit ClaimedFromOrder(auctionId, userId, buyAmount, sellAmount);\\r\\n }\\r\\n sendOutTokens(\\r\\n auctionId,\\r\\n sumAuctioningTokenAmount,\\r\\n sumBiddingTokenAmount,\\r\\n userId\\r\\n ); //[3]\\r\\n }\\r\\n\\r\\n function processFeesAndAuctioneerFunds(\\r\\n uint256 auctionId,\\r\\n uint256 fillVolumeOfAuctioneerOrder,\\r\\n uint64 auctioneerId,\\r\\n uint96 fullAuctionedAmount\\r\\n ) internal {\\r\\n uint256 feeAmount =\\r\\n fullAuctionedAmount.mul(auctionData[auctionId].feeNumerator).div(\\r\\n FEE_DENOMINATOR\\r\\n ); //[20]\\r\\n if (auctionData[auctionId].minFundingThresholdNotReached) {\\r\\n sendOutTokens(\\r\\n auctionId,\\r\\n fullAuctionedAmount.add(feeAmount),\\r\\n 0,\\r\\n auctioneerId\\r\\n ); //[4]\\r\\n } else {\\r\\n //[11]\\r\\n (, uint96 priceNumerator, uint96 priceDenominator) =\\r\\n auctionData[auctionId].clearingPriceOrder.decodeOrder();\\r\\n uint256 unsettledAuctionTokens =\\r\\n fullAuctionedAmount.sub(fillVolumeOfAuctioneerOrder);\\r\\n uint256 auctioningTokenAmount =\\r\\n unsettledAuctionTokens.add(\\r\\n feeAmount.mul(unsettledAuctionTokens).div(\\r\\n fullAuctionedAmount\\r\\n )\\r\\n );\\r\\n uint256 biddingTokenAmount =\\r\\n fillVolumeOfAuctioneerOrder.mul(priceDenominator).div(\\r\\n priceNumerator\\r\\n );\\r\\n sendOutTokens(\\r\\n auctionId,\\r\\n auctioningTokenAmount,\\r\\n biddingTokenAmount,\\r\\n auctioneerId\\r\\n ); //[5]\\r\\n sendOutTokens(\\r\\n auctionId,\\r\\n feeAmount.mul(fillVolumeOfAuctioneerOrder).div(\\r\\n fullAuctionedAmount\\r\\n ),\\r\\n 0,\\r\\n feeReceiverUserId\\r\\n ); //[7]\\r\\n }\\r\\n }\\r\\n\\r\\n function sendOutTokens(\\r\\n uint256 auctionId,\\r\\n uint256 auctioningTokenAmount,\\r\\n uint256 biddingTokenAmount,\\r\\n uint64 userId\\r\\n ) internal {\\r\\n address userAddress = registeredUsers.getAddressAt(userId);\\r\\n if (auctioningTokenAmount > 0) {\\r\\n auctionData[auctionId].auctioningToken.safeTransfer(\\r\\n userAddress,\\r\\n auctioningTokenAmount\\r\\n );\\r\\n }\\r\\n if (biddingTokenAmount > 0) {\\r\\n auctionData[auctionId].biddingToken.safeTransfer(\\r\\n userAddress,\\r\\n biddingTokenAmount\\r\\n );\\r\\n }\\r\\n }\\r\\n\\r\\n function registerUser(address user) public returns (uint64 userId) {\\r\\n numUsers = numUsers.add(1).toUint64();\\r\\n require(\\r\\n registeredUsers.insert(numUsers, user),\\r\\n \\\"User already registered\\\"\\r\\n );\\r\\n userId = numUsers;\\r\\n emit UserRegistration(user, userId);\\r\\n }\\r\\n\\r\\n function getUserId(address user) public returns (uint64 userId) {\\r\\n if (registeredUsers.hasAddress(user)) {\\r\\n userId = registeredUsers.getId(user);\\r\\n } else {\\r\\n userId = registerUser(user);\\r\\n emit NewUser(userId, user);\\r\\n }\\r\\n }\\r\\n\\r\\n function getSecondsRemainingInBatch(uint256 auctionId)\\r\\n public\\r\\n view\\r\\n returns (uint256)\\r\\n {\\r\\n if (auctionData[auctionId].auctionEndDate < block.timestamp) {\\r\\n return 0;\\r\\n }\\r\\n return auctionData[auctionId].auctionEndDate.sub(block.timestamp);\\r\\n }\\r\\n\\r\\n function containsOrder(uint256 auctionId, bytes32 order)\\r\\n public\\r\\n view\\r\\n returns (bool)\\r\\n {\\r\\n return sellOrders[auctionId].contains(order);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x8c14497bd253bed46a26f4858fffc60dbc7705475cd3ba2b952a40d7c0ad726c\"},\"contracts/allowListExamples/AllowListOffChainManaged.sol\":{\"content\":\"pragma solidity >=0.6.8;\\r\\nimport \\\"../interfaces/AllowListVerifier.sol\\\";\\r\\nimport \\\"../EasyAuction.sol\\\";\\r\\n\\r\\n// Idea was first mentioned in the blog:\\r\\n// https://medium.com/@PhABC/off-chain-whitelist-with-on-chain-verification-for-ethereum-smart-contracts-1563ca4b8f11\\r\\n\\r\\ncontract AllowListOffChainManaged {\\r\\n /// @dev The EIP-712 domain type hash used for computing the domain\\r\\n /// separator.\\r\\n bytes32 private constant DOMAIN_TYPE_HASH =\\r\\n keccak256(\\r\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\r\\n );\\r\\n\\r\\n /// @dev The EIP-712 domain name used for computing the domain separator.\\r\\n bytes32 private constant DOMAIN_NAME = keccak256(\\\"AccessManager\\\");\\r\\n\\r\\n /// @dev The EIP-712 domain version used for computing the domain separator.\\r\\n bytes32 private constant DOMAIN_VERSION = keccak256(\\\"v1\\\");\\r\\n\\r\\n /// @dev The domain separator used for signing orders that gets mixed in\\r\\n /// making signatures for different domains incompatible. This domain\\r\\n /// separator is computed following the EIP-712 standard and has replay\\r\\n /// protection mixed in so that signed orders are only valid for specific\\r\\n /// GPv2 contracts.\\r\\n bytes32 public immutable domainSeparator;\\r\\n\\r\\n constructor() public {\\r\\n // NOTE: Currently, the only way to get the chain ID in solidity is\\r\\n // using assembly.\\r\\n uint256 chainId;\\r\\n // solhint-disable-next-line no-inline-assembly\\r\\n assembly {\\r\\n chainId := chainid()\\r\\n }\\r\\n\\r\\n domainSeparator = keccak256(\\r\\n abi.encode(\\r\\n DOMAIN_TYPE_HASH,\\r\\n DOMAIN_NAME,\\r\\n DOMAIN_VERSION,\\r\\n chainId,\\r\\n address(this)\\r\\n )\\r\\n );\\r\\n }\\r\\n\\r\\n function isAllowed(\\r\\n address user,\\r\\n uint256 auctionId,\\r\\n bytes calldata callData\\r\\n ) external view returns (bytes4) {\\r\\n return isAllowedBy(user, auctionId, msg.sender, callData);\\r\\n }\\r\\n\\r\\n function isAllowedBy(\\r\\n address user,\\r\\n uint256 auctionId,\\r\\n address allower,\\r\\n bytes calldata callData\\r\\n ) public view returns (bytes4) {\\r\\n uint8 v;\\r\\n bytes32 r;\\r\\n bytes32 s;\\r\\n (v, r, s) = abi.decode(callData, (uint8, bytes32, bytes32));\\r\\n bytes32 hash = keccak256(abi.encode(domainSeparator, user, auctionId));\\r\\n address signer =\\r\\n ecrecover(\\r\\n keccak256(\\r\\n abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash)\\r\\n ),\\r\\n v,\\r\\n r,\\r\\n s\\r\\n );\\r\\n bytes memory allowListData =\\r\\n EasyAuction(allower).auctionAccessData(auctionId);\\r\\n if (abi.decode(allowListData, (address)) == signer) {\\r\\n return AllowListVerifierHelper.MAGICVALUE;\\r\\n } else {\\r\\n return bytes4(0);\\r\\n }\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x6cf7ab8344ef1b61cd39cb8f87eeb8effa66966d0e6856c991a1d7f22f67cddc\"},\"contracts/interfaces/AllowListVerifier.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-or-later\\r\\npragma solidity >=0.6.8;\\r\\n\\r\\nlibrary AllowListVerifierHelper {\\r\\n /// @dev Value returned by a call to `isAllowed` if the check\\r\\n /// was successful. The value is defined as:\\r\\n /// bytes4(keccak256(\\\"isAllowed(address,uint256,bytes)\\\"))\\r\\n bytes4 internal constant MAGICVALUE = 0x19a05a7e;\\r\\n}\\r\\n\\r\\n///\\r\\n/// @dev Standardized interface for an allowList manager for easyAuction\\r\\n/// The interface was inspired by EIP-1271\\r\\ninterface AllowListVerifier {\\r\\n /// @dev Should return whether the a specific user has access to an auction\\r\\n /// by returning the magic value from AllowListVerifierHelper\\r\\n function isAllowed(\\r\\n address user,\\r\\n uint256 auctionId,\\r\\n bytes calldata callData\\r\\n ) external view returns (bytes4);\\r\\n}\\r\\n\",\"keccak256\":\"0xe646b09ca1a8756d2b10c4d50370cecb6a88c4c63bf56a5f83af3794c7f41a80\",\"license\":\"LGPL-3.0-or-later\"},\"contracts/libraries/IdToAddressBiMap.sol\":{\"content\":\"pragma solidity ^0.6.0;\\r\\n\\r\\n///////////////////////////////////////////////////////////////////////////////////////////////////////////\\r\\n// Contract does not have test coverage, as it was nearly copied from:\\r\\n// https://github.com/gnosis/solidity-data-structures/blob/master/contracts/libraries/IdToAddressBiMap.sol\\r\\n// The only change is uint16 -> uint64\\r\\n///////////////////////////////////////////////////////////////////////////////////////////////////////////\\r\\n\\r\\nlibrary IdToAddressBiMap {\\r\\n struct Data {\\r\\n mapping(uint64 => address) idToAddress;\\r\\n mapping(address => uint64) addressToId;\\r\\n }\\r\\n\\r\\n function hasId(Data storage self, uint64 id) internal view returns (bool) {\\r\\n return self.idToAddress[id + 1] != address(0);\\r\\n }\\r\\n\\r\\n function hasAddress(Data storage self, address addr)\\r\\n internal\\r\\n view\\r\\n returns (bool)\\r\\n {\\r\\n return self.addressToId[addr] != 0;\\r\\n }\\r\\n\\r\\n function getAddressAt(Data storage self, uint64 id)\\r\\n internal\\r\\n view\\r\\n returns (address)\\r\\n {\\r\\n require(hasId(self, id), \\\"Must have ID to get Address\\\");\\r\\n return self.idToAddress[id + 1];\\r\\n }\\r\\n\\r\\n function getId(Data storage self, address addr)\\r\\n internal\\r\\n view\\r\\n returns (uint64)\\r\\n {\\r\\n require(hasAddress(self, addr), \\\"Must have Address to get ID\\\");\\r\\n return self.addressToId[addr] - 1;\\r\\n }\\r\\n\\r\\n function insert(\\r\\n Data storage self,\\r\\n uint64 id,\\r\\n address addr\\r\\n ) internal returns (bool) {\\r\\n require(addr != address(0), \\\"Cannot insert zero address\\\");\\r\\n require(id != uint64(-1), \\\"Cannot insert max uint64\\\");\\r\\n // Ensure bijectivity of the mappings\\r\\n if (\\r\\n self.addressToId[addr] != 0 ||\\r\\n self.idToAddress[id + 1] != address(0)\\r\\n ) {\\r\\n return false;\\r\\n }\\r\\n self.idToAddress[id + 1] = addr;\\r\\n self.addressToId[addr] = id + 1;\\r\\n return true;\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x44c23c11087ac487704504e99658ae1303d1cad5d5ba0b171a61adf04e2cd5ea\"},\"contracts/libraries/IterableOrderedOrderSet.sol\":{\"content\":\"pragma solidity >=0.6.8;\\r\\n\\r\\nimport \\\"@openzeppelin/contracts/math/SafeMath.sol\\\";\\r\\n\\r\\nlibrary IterableOrderedOrderSet {\\r\\n using SafeMath for uint96;\\r\\n using IterableOrderedOrderSet for bytes32;\\r\\n\\r\\n // represents smallest possible value for an order under comparison of fn smallerThan()\\r\\n bytes32 internal constant QUEUE_START =\\r\\n 0x0000000000000000000000000000000000000000000000000000000000000001;\\r\\n // represents highest possible value for an order under comparison of fn smallerThan()\\r\\n bytes32 internal constant QUEUE_END =\\r\\n 0xffffffffffffffffffffffffffffffffffffffff000000000000000000000001;\\r\\n\\r\\n /// The struct is used to implement a modified version of a doubly linked\\r\\n /// list with sorted elements. The list starts from QUEUE_START to\\r\\n /// QUEUE_END, and each node keeps track of its predecessor and successor.\\r\\n /// Nodes can be added or removed.\\r\\n ///\\r\\n /// `next` and `prev` have a different role. The list is supposed to be\\r\\n /// traversed with `next`. If `next` is empty, the node is not part of the\\r\\n /// list. However, `prev` might be set for elements that are not in the\\r\\n /// list, which is why it should not be used for traversing. Having a `prev`\\r\\n /// set for elements not in the list is used to keep track of the history of\\r\\n /// the position in the list of a removed element.\\r\\n struct Data {\\r\\n mapping(bytes32 => bytes32) nextMap;\\r\\n mapping(bytes32 => bytes32) prevMap;\\r\\n }\\r\\n\\r\\n struct Order {\\r\\n uint64 owner;\\r\\n uint96 buyAmount;\\r\\n uint96 sellAmount;\\r\\n }\\r\\n\\r\\n function initializeEmptyList(Data storage self) internal {\\r\\n self.nextMap[QUEUE_START] = QUEUE_END;\\r\\n self.prevMap[QUEUE_END] = QUEUE_START;\\r\\n }\\r\\n\\r\\n function isEmpty(Data storage self) internal view returns (bool) {\\r\\n return self.nextMap[QUEUE_START] == QUEUE_END;\\r\\n }\\r\\n\\r\\n function insert(\\r\\n Data storage self,\\r\\n bytes32 elementToInsert,\\r\\n bytes32 elementBeforeNewOne\\r\\n ) internal returns (bool) {\\r\\n (, , uint96 denominator) = decodeOrder(elementToInsert);\\r\\n require(denominator != uint96(0), \\\"Inserting zero is not supported\\\");\\r\\n require(\\r\\n elementToInsert != QUEUE_START && elementToInsert != QUEUE_END,\\r\\n \\\"Inserting element is not valid\\\"\\r\\n );\\r\\n if (contains(self, elementToInsert)) {\\r\\n return false;\\r\\n }\\r\\n if (\\r\\n elementBeforeNewOne != QUEUE_START &&\\r\\n self.prevMap[elementBeforeNewOne] == bytes32(0)\\r\\n ) {\\r\\n return false;\\r\\n }\\r\\n if (!elementBeforeNewOne.smallerThan(elementToInsert)) {\\r\\n return false;\\r\\n }\\r\\n\\r\\n // `elementBeforeNewOne` might have been removed during the time it\\r\\n // took to the transaction calling this function to be mined, so\\r\\n // the new order cannot be appended directly to this. We follow the\\r\\n // history of previous links backwards until we find an element in\\r\\n // the list from which to start our search.\\r\\n // Note that following the link backwards returns elements that are\\r\\n // before `elementBeforeNewOne` in sorted order.\\r\\n while (self.nextMap[elementBeforeNewOne] == bytes32(0)) {\\r\\n elementBeforeNewOne = self.prevMap[elementBeforeNewOne];\\r\\n }\\r\\n\\r\\n // `elementBeforeNewOne` belongs now to the linked list. We search the\\r\\n // largest entry that is smaller than the element to insert.\\r\\n bytes32 previous;\\r\\n bytes32 current = elementBeforeNewOne;\\r\\n do {\\r\\n previous = current;\\r\\n current = self.nextMap[current];\\r\\n } while (current.smallerThan(elementToInsert));\\r\\n // Note: previous < elementToInsert < current\\r\\n self.nextMap[previous] = elementToInsert;\\r\\n self.prevMap[current] = elementToInsert;\\r\\n self.prevMap[elementToInsert] = previous;\\r\\n self.nextMap[elementToInsert] = current;\\r\\n\\r\\n return true;\\r\\n }\\r\\n\\r\\n /// The element is removed from the linked list, but the node retains\\r\\n /// information on which predecessor it had, so that a node in the chain\\r\\n /// can be reached by following the predecessor chain of deleted elements.\\r\\n function removeKeepHistory(Data storage self, bytes32 elementToRemove)\\r\\n internal\\r\\n returns (bool)\\r\\n {\\r\\n if (!contains(self, elementToRemove)) {\\r\\n return false;\\r\\n }\\r\\n bytes32 previousElement = self.prevMap[elementToRemove];\\r\\n bytes32 nextElement = self.nextMap[elementToRemove];\\r\\n self.nextMap[previousElement] = nextElement;\\r\\n self.prevMap[nextElement] = previousElement;\\r\\n self.nextMap[elementToRemove] = bytes32(0);\\r\\n return true;\\r\\n }\\r\\n\\r\\n /// Remove an element from the chain, clearing all related storage.\\r\\n /// Note that no elements should be inserted using as a reference point a\\r\\n /// node deleted after calling `remove`, since an element in the `prev`\\r\\n /// chain might be missing.\\r\\n function remove(Data storage self, bytes32 elementToRemove)\\r\\n internal\\r\\n returns (bool)\\r\\n {\\r\\n bool result = removeKeepHistory(self, elementToRemove);\\r\\n if (result) {\\r\\n self.prevMap[elementToRemove] = bytes32(0);\\r\\n }\\r\\n return result;\\r\\n }\\r\\n\\r\\n function contains(Data storage self, bytes32 value)\\r\\n internal\\r\\n view\\r\\n returns (bool)\\r\\n {\\r\\n if (value == QUEUE_START) {\\r\\n return false;\\r\\n }\\r\\n // Note: QUEUE_END is not contained in the list since it has no\\r\\n // successor.\\r\\n return self.nextMap[value] != bytes32(0);\\r\\n }\\r\\n\\r\\n // @dev orders are ordered by\\r\\n // 1. their price - buyAmount/sellAmount\\r\\n // 2. by the sellAmount\\r\\n // 3. their userId,\\r\\n function smallerThan(bytes32 orderLeft, bytes32 orderRight)\\r\\n internal\\r\\n pure\\r\\n returns (bool)\\r\\n {\\r\\n (\\r\\n uint64 userIdLeft,\\r\\n uint96 priceNumeratorLeft,\\r\\n uint96 priceDenominatorLeft\\r\\n ) = decodeOrder(orderLeft);\\r\\n (\\r\\n uint64 userIdRight,\\r\\n uint96 priceNumeratorRight,\\r\\n uint96 priceDenominatorRight\\r\\n ) = decodeOrder(orderRight);\\r\\n\\r\\n if (\\r\\n priceNumeratorLeft.mul(priceDenominatorRight) <\\r\\n priceNumeratorRight.mul(priceDenominatorLeft)\\r\\n ) return true;\\r\\n if (\\r\\n priceNumeratorLeft.mul(priceDenominatorRight) >\\r\\n priceNumeratorRight.mul(priceDenominatorLeft)\\r\\n ) return false;\\r\\n\\r\\n if (priceNumeratorLeft < priceNumeratorRight) return true;\\r\\n if (priceNumeratorLeft > priceNumeratorRight) return false;\\r\\n require(\\r\\n userIdLeft != userIdRight,\\r\\n \\\"user is not allowed to place same order twice\\\"\\r\\n );\\r\\n if (userIdLeft < userIdRight) {\\r\\n return true;\\r\\n }\\r\\n return false;\\r\\n }\\r\\n\\r\\n function first(Data storage self) internal view returns (bytes32) {\\r\\n require(!isEmpty(self), \\\"Trying to get first from empty set\\\");\\r\\n return self.nextMap[QUEUE_START];\\r\\n }\\r\\n\\r\\n function next(Data storage self, bytes32 value)\\r\\n internal\\r\\n view\\r\\n returns (bytes32)\\r\\n {\\r\\n require(value != QUEUE_END, \\\"Trying to get next of last element\\\");\\r\\n bytes32 nextElement = self.nextMap[value];\\r\\n require(\\r\\n nextElement != bytes32(0),\\r\\n \\\"Trying to get next of non-existent element\\\"\\r\\n );\\r\\n return nextElement;\\r\\n }\\r\\n\\r\\n function decodeOrder(bytes32 _orderData)\\r\\n internal\\r\\n pure\\r\\n returns (\\r\\n uint64 userId,\\r\\n uint96 buyAmount,\\r\\n uint96 sellAmount\\r\\n )\\r\\n {\\r\\n // Note: converting to uint discards the binary digits that do not fit\\r\\n // the type.\\r\\n userId = uint64(uint256(_orderData) >> 192);\\r\\n buyAmount = uint96(uint256(_orderData) >> 96);\\r\\n sellAmount = uint96(uint256(_orderData));\\r\\n }\\r\\n\\r\\n function encodeOrder(\\r\\n uint64 userId,\\r\\n uint96 buyAmount,\\r\\n uint96 sellAmount\\r\\n ) internal pure returns (bytes32) {\\r\\n return\\r\\n bytes32(\\r\\n (uint256(userId) << 192) +\\r\\n (uint256(buyAmount) << 96) +\\r\\n uint256(sellAmount)\\r\\n );\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0x9510258dca14a3327710d516a1b5c0e7147e20ac8f5a29a98048d97878ff1dac\"},\"contracts/libraries/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\r\\n\\r\\npragma solidity >=0.6.0 <0.8.0;\\r\\n\\r\\n/**\\r\\n * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow\\r\\n * checks.\\r\\n *\\r\\n * Logic was copied and modified from here: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/SafeCast.sol\\r\\n */\\r\\nlibrary SafeCast {\\r\\n function toUint96(uint256 value) internal pure returns (uint96) {\\r\\n require(value < 2**96, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\r\\n return uint96(value);\\r\\n }\\r\\n\\r\\n function toUint64(uint256 value) internal pure returns (uint64) {\\r\\n require(value < 2**64, \\\"SafeCast: value doesn't fit in 64 bits\\\");\\r\\n return uint64(value);\\r\\n }\\r\\n}\\r\\n\",\"keccak256\":\"0xe9d43c6764bad8042246919c329bb1cf5385ba190374f64f135982b8d1c0bbdd\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x60a060405234801561001057600080fd5b5060004690507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f64aea53a8993ca7da1a35d4bd452fdb6171945e1d5fa9b7b34165966167f81c27f0984d5efd47d99151ae1be065a709e56c602102f24c1abc4008eb3f815a8d2178330604051602001808681526020018581526020018481526020018381526020018273ffffffffffffffffffffffffffffffffffffffff168152602001955050505050506040516020818303038152906040528051906020012060808181525050506080516105e76100fa60003980610297528061058f52506105e76000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806319a05a7e146100465780631c841c421461011c578063f698da2514610212575b600080fd5b6100e76004803603606081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156100a357600080fd5b8201836020820111156100b557600080fd5b803590602001918460018302840111640100000000831117156100d757600080fd5b9091929391929390505050610230565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b6101dd6004803603608081101561013257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561019957600080fd5b8201836020820111156101ab57600080fd5b803590602001918460018302840111640100000000831117156101cd57600080fd5b9091929391929390505050610249565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b61021a61058d565b6040518082815260200191505060405180910390f35b600061023f8585338686610249565b9050949350505050565b6000806000808585606081101561025f57600080fd5b81019080803560ff169060200190929190803590602001909291908035906020019092919050505080935081945082955050505060007f00000000000000000000000000000000000000000000000000000000000000008a8a604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052805190602001209050600060018260405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012086868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156103ae573d6000803e3d6000fd5b50505060206040510351905060608973ffffffffffffffffffffffffffffffffffffffff1663f59c2f068c6040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561040d57600080fd5b505afa158015610421573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250602081101561044b57600080fd5b810190808051604051939291908464010000000082111561046b57600080fd5b8382019150602082018581111561048157600080fd5b825186600182028301116401000000008211171561049e57600080fd5b8083526020830192505050908051906020019080838360005b838110156104d25780820151818401526020810190506104b7565b50505050905090810190601f1680156104ff5780820380516001836020036101000a031916815260200191505b5060405250505090508173ffffffffffffffffffffffffffffffffffffffff1681806020019051602081101561053457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161415610576576319a05a7e60e01b9650505050505050610584565b600060e01b96505050505050505b95945050505050565b7f00000000000000000000000000000000000000000000000000000000000000008156fea2646970667358221220d2e1085587cf2a04b429e878578aec6a21ad5d9c2f0b847f4c8118455b9bb18164736f6c634300060c0033", "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806319a05a7e146100465780631c841c421461011c578063f698da2514610212575b600080fd5b6100e76004803603606081101561005c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001906401000000008111156100a357600080fd5b8201836020820111156100b557600080fd5b803590602001918460018302840111640100000000831117156100d757600080fd5b9091929391929390505050610230565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b6101dd6004803603608081101561013257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561019957600080fd5b8201836020820111156101ab57600080fd5b803590602001918460018302840111640100000000831117156101cd57600080fd5b9091929391929390505050610249565b60405180827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200191505060405180910390f35b61021a61058d565b6040518082815260200191505060405180910390f35b600061023f8585338686610249565b9050949350505050565b6000806000808585606081101561025f57600080fd5b81019080803560ff169060200190929190803590602001909291908035906020019092919050505080935081945082955050505060007f00000000000000000000000000000000000000000000000000000000000000008a8a604051602001808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052805190602001209050600060018260405160200180807f19457468657265756d205369676e6564204d6573736167653a0a333200000000815250601c018281526020019150506040516020818303038152906040528051906020012086868660405160008152602001604052604051808581526020018460ff1681526020018381526020018281526020019450505050506020604051602081039080840390855afa1580156103ae573d6000803e3d6000fd5b50505060206040510351905060608973ffffffffffffffffffffffffffffffffffffffff1663f59c2f068c6040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561040d57600080fd5b505afa158015610421573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250602081101561044b57600080fd5b810190808051604051939291908464010000000082111561046b57600080fd5b8382019150602082018581111561048157600080fd5b825186600182028301116401000000008211171561049e57600080fd5b8083526020830192505050908051906020019080838360005b838110156104d25780820151818401526020810190506104b7565b50505050905090810190601f1680156104ff5780820380516001836020036101000a031916815260200191505b5060405250505090508173ffffffffffffffffffffffffffffffffffffffff1681806020019051602081101561053457600080fd5b810190808051906020019092919050505073ffffffffffffffffffffffffffffffffffffffff161415610576576319a05a7e60e01b9650505050505050610584565b600060e01b96505050505050505b95945050505050565b7f00000000000000000000000000000000000000000000000000000000000000008156fea2646970667358221220d2e1085587cf2a04b429e878578aec6a21ad5d9c2f0b847f4c8118455b9bb18164736f6c634300060c0033", "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 } }