From 06a4c8f09f047a8adcd756fb49409699bc3a0888 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Thu, 21 Sep 2023 12:25:42 +0400 Subject: [PATCH 01/32] first impl --- contracts/SettlementExtension.sol | 154 ++++++++++++++++++++++++++++++ 1 file changed, 154 insertions(+) create mode 100644 contracts/SettlementExtension.sol diff --git a/contracts/SettlementExtension.sol b/contracts/SettlementExtension.sol new file mode 100644 index 00000000..93530ebd --- /dev/null +++ b/contracts/SettlementExtension.sol @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.19; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@1inch/limit-order-protocol-contract/contracts/interfaces/IPreInteraction.sol"; +import "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol"; +import "./FeeBankCharger.sol"; + +/** + * @title Settlement contract + * @notice Contract to execute limit orders settlement, created by Fusion mode. + */ +contract SettlementExtension is IPreInteraction, FeeBankCharger { + using SafeERC20 for IERC20; + using AddressLib for Address; + + error OnlyLimitOrderProtocol(); + error ResolverIsNotWhitelisted(); + + uint256 private constant _TAKING_FEE_BASE = 1e9; + uint256 private constant _ORDER_FEE_BASE_POINTS = 1e15; + uint256 private constant _BASE_POINTS = 10_000_000; // 100% + uint256 private constant _RESOLVER_ADDRESS_MASK = 0xffffffffffffffffffff; + + IOrderMixin private immutable _limitOrderProtocol; + + /// @dev Modifier to check if the caller is the limit order protocol contract. + modifier onlyLimitOrderProtocol { + if (msg.sender != address(_limitOrderProtocol)) revert OnlyLimitOrderProtocol(); + _; + } + + /** + * @notice Initializes the contract. + * @param limitOrderProtocol The limit order protocol contract. + * @param token The token to charge protocol fees in. + */ + constructor(IOrderMixin limitOrderProtocol, IERC20 token) + FeeBankCharger(token) + { + _limitOrderProtocol = limitOrderProtocol; + } + + /// struct AuctionDetails { + /// bytes4 auctionStartTime; + /// bytes3 auctionDuration; + /// bytes3 initialRateBump; + /// (bytes3,bytes2)[N] pointsAndTimeDeltas; + /// } + + function getMakingAmount(uint256 orderMakingAmount, uint256 orderTakingAmount, bytes calldata auctionDetails) external view returns (uint256) { + uint256 requestedTakingAmount = uint256(bytes32(msg.data[msg.data.length - 0x60:])); + uint256 rateBump = _getRateBump(auctionDetails); + return orderMakingAmount * requestedTakingAmount * (_BASE_POINTS + rateBump) / _BASE_POINTS / orderTakingAmount; + } + + function getTakingAmount(uint256 orderMakingAmount, uint256 orderTakingAmount, bytes calldata auctionDetails) external view returns (uint256) { + uint256 requestedMakingAmount = uint256(bytes32(msg.data[msg.data.length - 0x60:])); + uint256 rateBump = _getRateBump(auctionDetails); + return (orderTakingAmount * requestedMakingAmount * (_BASE_POINTS + rateBump) + orderMakingAmount * _BASE_POINTS - 1) / _BASE_POINTS / orderMakingAmount; + } + + function _getRateBump(bytes calldata auctionDetails) private view returns (uint256) { + uint256 auctionStartTime = uint32(bytes4(auctionDetails[0:4])); + uint256 auctionFinishTime = auctionStartTime + uint24(bytes3(auctionDetails[4:7])); + uint256 initialRateBump = uint24(bytes3(auctionDetails[7:10])); + + if (block.timestamp <= auctionStartTime) { + return initialRateBump; + } else if (block.timestamp >= auctionFinishTime) { + return 0; // Means 0% bump + } + + auctionDetails = auctionDetails[10:]; + uint256 pointsSize = auctionDetails.length / 5; + uint256 currentPointTime = auctionStartTime; + uint256 currentRateBump = initialRateBump; + + for (uint256 i = 0; i < pointsSize; i++) { + uint256 nextRateBump = uint24(bytes3(auctionDetails[:3])); + uint256 nextPointTime = currentPointTime + uint16(bytes2(auctionDetails[3:5])); + if (block.timestamp <= nextPointTime) { + return ((block.timestamp - currentPointTime) * nextRateBump + (nextPointTime - block.timestamp) * currentRateBump) / (nextPointTime - currentPointTime); + } + currentRateBump = nextRateBump; + currentPointTime = nextPointTime; + } + + return (auctionFinishTime - block.timestamp) * currentRateBump / (auctionFinishTime - currentPointTime); + } + + /// struct WhitelistDetails { + /// bytes4 auctionStartTime; + /// (bytes10,bytes2)[N] resolversAddressesAndTimeDeltas; + /// } + + function _isWhitelisted(bytes calldata whitelist, address resolver) private view returns (bool) { + uint256 allowedTime = uint32(bytes4(whitelist[0:4])); // initially set to auction start time + whitelist = whitelist[4:]; + uint256 whitelistSize = whitelist.length / 12; + uint80 maskedResolverAddress = uint80(uint160(resolver) & _RESOLVER_ADDRESS_MASK); + for (uint256 i = 0; i < whitelistSize; i++) { + uint80 whitelistedAddress = uint80(bytes10(whitelist[:10])); + allowedTime += uint16(bytes2(whitelist[10:12])); // add next time delta + if (maskedResolverAddress == whitelistedAddress) { + return allowedTime <= block.timestamp; + } else if (allowedTime > block.timestamp) { + return false; + } + whitelist = whitelist[12:]; + } + return false; + } + + function preInteraction( + IOrderMixin.Order calldata order, + bytes32, + address taker, + uint256 makingAmount, + uint256 takingAmount, + uint256, + bytes calldata extraData + ) external onlyLimitOrderProtocol { + (uint256 resolverFee, address integrator, uint256 integrationFee, bytes calldata whitelist) = _parseFeeData(extraData, order.makingAmount, makingAmount, takingAmount); + if (!_isWhitelisted(whitelist, taker)) revert ResolverIsNotWhitelisted(); + _chargeFee(taker, resolverFee); + if (integrationFee > 0) { + IERC20(order.takerAsset.get()).safeTransferFrom(taker, integrator, integrationFee); + } + } + + function _parseFeeData( + bytes calldata extraData, + uint256 orderMakingAmount, + uint256 actualMakingAmount, + uint256 actualTakingAmount + ) private pure returns (uint256 resolverFee, address integrator, uint256 integrationFee, bytes calldata whitelist) { + bytes1 feeType = extraData[0]; + extraData = extraData[1:]; + if (feeType & 0x01 == 0x01) { + // resolverFee enabled + resolverFee = (_ORDER_FEE_BASE_POINTS * uint256(uint32(bytes4(extraData[:4]))) * actualMakingAmount + orderMakingAmount - 1) / orderMakingAmount; + extraData = extraData[4:]; + } + if (feeType & 0x02 == 0x02) { + // integratorFee enabled + integrator = address(bytes20(extraData[:20])); + integrationFee = actualTakingAmount * uint256(uint32(bytes4(extraData[20:24]))) / _TAKING_FEE_BASE; + extraData = extraData[24:]; + } + whitelist = extraData; + } +} From 600fbf427b49d6920c4586764d1d8e6a6fc87041 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Thu, 21 Sep 2023 13:16:29 +0400 Subject: [PATCH 02/32] add measure gas test --- contracts/SettlementExtension.sol | 8 +++++ test/MeasureGas.js | 57 ++++++++++++++++++++++++++++--- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/contracts/SettlementExtension.sol b/contracts/SettlementExtension.sol index 93530ebd..68bf4160 100644 --- a/contracts/SettlementExtension.sol +++ b/contracts/SettlementExtension.sol @@ -130,6 +130,14 @@ contract SettlementExtension is IPreInteraction, FeeBankCharger { } } + /// struct FeeData { + /// bytes1 feeTypes; 1 = resolverFee, 2 = intergrationFee + /// bytes4 resolverFee; optional + /// bytes20 integrator; optional + /// bytes4 integrationFee; optional + /// bytes whitelist; + /// } + function _parseFeeData( bytes calldata extraData, uint256 orderMakingAmount, diff --git a/test/MeasureGas.js b/test/MeasureGas.js index 118689de..f39d9c40 100644 --- a/test/MeasureGas.js +++ b/test/MeasureGas.js @@ -1,7 +1,7 @@ const hre = require('hardhat'); const { ethers } = hre; const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { expect, ether, trim0x } = require('@1inch/solidity-utils'); +const { time, expect, ether, trim0x } = require('@1inch/solidity-utils'); const { deploySwapTokens, getChainId, deployContract } = require('./helpers/fixtures'); const { buildOrder, signOrder, compactSignature, fillWithMakingAmount, buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); const { buildFusions } = require('./helpers/fusionUtils'); @@ -26,6 +26,7 @@ describe('MeasureGas', function () { await weth.deposit({ value: ether('1') }); await weth.connect(addrs[1]).deposit({ value: ether('1') }); + const settlementExtension = await deployContract('SettlementExtension', [swap.address, inch.address]); const settlement = await deployContract('Settlement', [swap.address, inch.address]); const resolvers = []; for (let i = 0; i < resolversNumber; i++) { @@ -36,19 +37,19 @@ describe('MeasureGas', function () { await inch.approve(feeBank.address, ether('100')); await feeBank.depositFor(resolvers[0].address, ether('100')); - return { dai, weth, swap, settlement, feeBank, resolvers }; + return { dai, weth, swap, settlement, settlementExtension, feeBank, resolvers }; } async function initContractsAndApproves() { - const { dai, weth, swap, settlement, feeBank, resolvers } = await initContracts(); + const { dai, weth, swap, settlement, settlementExtension, feeBank, resolvers } = await initContracts(); await dai.approve(swap.address, ether('100')); await dai.connect(addrs[1]).approve(swap.address, ether('100')); await weth.approve(swap.address, ether('1')); await weth.connect(addrs[1]).approve(swap.address, ether('1')); - return { dai, weth, swap, settlement, feeBank, resolvers }; + return { dai, weth, swap, settlement, settlementExtension, feeBank, resolvers }; } - it('1 fill for 1 order', async function () { + it.only('1 fill for 1 order', async function () { const { dai, weth, swap, settlement, resolvers } = await loadFixture(initContractsAndApproves); const { fusions: [fusionDetails], hashes: [fusionDetailsHash], resolvers: fusionResolvers } = await buildFusions([ @@ -97,6 +98,52 @@ describe('MeasureGas', function () { await expect(tx).to.changeTokenBalances(weth, [addrs[0], addrs[1]], [ether('-0.1'), ether('0.1')]); }); + it.only('extension 1 fill for 1 order', async function () { + const { dai, weth, swap, settlementExtension } = await loadFixture(initContractsAndApproves); + + const auctionStartTime = await time.latest(); + const auctionDetails = ethers.utils.solidityPack( + ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0] + ); + + const order = buildOrder({ + maker: addrs[1].address, + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), + }, { + makingAmountGetter: settlementExtension.address + trim0x(settlementExtension.interface.encodeFunctionData( + 'getMakingAmount', [ether('100'), ether('0.1'), auctionDetails] + )), + takingAmountGetter: settlementExtension.address + trim0x(settlementExtension.interface.encodeFunctionData( + 'getTakingAmount', [ether('100'), ether('0.1'), auctionDetails] + )), + preInteraction: settlementExtension.address + trim0x(ethers.utils.solidityPack( + ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + addrs[0].address.substring(22), 0] + )), + }); + + console.log(settlementExtension.address); + + const { r, vs } = compactSignature(await signOrder(order, chainId, swap.address, addrs[1])); + + await weth.approve(swap.address, ether('0.1')); + + const tx = await swap.fillOrderExt( + order, + r, + vs, + ether('100'), + fillWithMakingAmount('0'), + order.extension, + ); + console.log(`1 fill for 1 order gasUsed: ${(await tx.wait()).gasUsed}`); + await expect(tx).to.changeTokenBalances(dai, [addrs[0], addrs[1]], [ether('100'), ether('-100')]); + await expect(tx).to.changeTokenBalances(weth, [addrs[0], addrs[1]], [ether('-0.1'), ether('0.1')]); + }); + it('1 fill for 5 orders in a batch', async function () { const { dai, weth, swap, settlement, resolvers } = await loadFixture(initContractsAndApproves); From 3f1ef67975b36ea7aec3e2e446d45d545073dbd7 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Thu, 21 Sep 2023 13:17:40 +0400 Subject: [PATCH 03/32] cleanup --- test/MeasureGas.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/MeasureGas.js b/test/MeasureGas.js index f39d9c40..3e49b57f 100644 --- a/test/MeasureGas.js +++ b/test/MeasureGas.js @@ -125,8 +125,6 @@ describe('MeasureGas', function () { )), }); - console.log(settlementExtension.address); - const { r, vs } = compactSignature(await signOrder(order, chainId, swap.address, addrs[1])); await weth.approve(swap.address, ether('0.1')); From 2febf59d92e9ed62f7b26c98ff00d00357426aaa Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Thu, 21 Sep 2023 13:58:11 +0400 Subject: [PATCH 04/32] simplify --- test/MeasureGas.js | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/test/MeasureGas.js b/test/MeasureGas.js index 3e49b57f..dcd29462 100644 --- a/test/MeasureGas.js +++ b/test/MeasureGas.js @@ -66,20 +66,6 @@ describe('MeasureGas', function () { order.salt = fusionDetailsHash; const { r, vs } = compactSignature(await signOrder(order, chainId, swap.address, addrs[1])); - const resolverCalldata = abiCoder.encode( - ['address[]', 'bytes[]'], - [ - [weth.address], - [ - weth.interface.encodeFunctionData('transferFrom', [ - addrs[0].address, - resolvers[0].address, - ether('0.1'), - ]), - ], - ], - ); - const fillOrderToData = swap.interface.encodeFunctionData('fillOrderTo', [ order, r, @@ -87,15 +73,15 @@ describe('MeasureGas', function () { ether('100'), fillWithMakingAmount('0'), resolvers[0].address, - settlement.address + '01' + trim0x(fusionDetails) + trim0x(resolverCalldata), + settlement.address + '01' + trim0x(fusionDetails), ]) + trim0x(fusionResolvers); - await weth.approve(resolvers[0].address, ether('0.1')); + await weth.transfer(resolvers[0].address, ether('0.1')); const tx = await resolvers[0].settleOrders(fillOrderToData); console.log(`1 fill for 1 order gasUsed: ${(await tx.wait()).gasUsed}`); await expect(tx).to.changeTokenBalances(dai, [resolvers[0], addrs[1]], [ether('100'), ether('-100')]); - await expect(tx).to.changeTokenBalances(weth, [addrs[0], addrs[1]], [ether('-0.1'), ether('0.1')]); + await expect(tx).to.changeTokenBalances(weth, [resolvers[0], addrs[1]], [ether('-0.1'), ether('0.1')]); }); it.only('extension 1 fill for 1 order', async function () { From 7c4cc0e5c8b711f34961c0990575a07bbc11660f Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Wed, 4 Oct 2023 18:16:08 +0400 Subject: [PATCH 05/32] bump limit-order version --- contracts/SettlementExtension.sol | 42 +++++++++++++++++++++---------- package.json | 2 +- yarn.lock | 18 ++++++------- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/contracts/SettlementExtension.sol b/contracts/SettlementExtension.sol index 68bf4160..5920f849 100644 --- a/contracts/SettlementExtension.sol +++ b/contracts/SettlementExtension.sol @@ -3,7 +3,8 @@ pragma solidity 0.8.19; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@1inch/limit-order-protocol-contract/contracts/interfaces/IPreInteraction.sol"; +import "@1inch/limit-order-protocol-contract/contracts/interfaces/IPostInteraction.sol"; +import "@1inch/limit-order-protocol-contract/contracts/interfaces/IAmountGetter.sol"; import "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol"; import "./FeeBankCharger.sol"; @@ -11,7 +12,7 @@ import "./FeeBankCharger.sol"; * @title Settlement contract * @notice Contract to execute limit orders settlement, created by Fusion mode. */ -contract SettlementExtension is IPreInteraction, FeeBankCharger { +contract SettlementExtension is IPostInteraction, IAmountGetter, FeeBankCharger { using SafeERC20 for IERC20; using AddressLib for Address; @@ -49,16 +50,30 @@ contract SettlementExtension is IPreInteraction, FeeBankCharger { /// (bytes3,bytes2)[N] pointsAndTimeDeltas; /// } - function getMakingAmount(uint256 orderMakingAmount, uint256 orderTakingAmount, bytes calldata auctionDetails) external view returns (uint256) { - uint256 requestedTakingAmount = uint256(bytes32(msg.data[msg.data.length - 0x60:])); - uint256 rateBump = _getRateBump(auctionDetails); - return orderMakingAmount * requestedTakingAmount * (_BASE_POINTS + rateBump) / _BASE_POINTS / orderTakingAmount; + function getMakingAmount( + IOrderMixin.Order calldata order, + bytes calldata /* extension */, + bytes32 /* orderHash */, + address /* taker */, + uint256 takingAmount, + uint256 /* remainingMakingAmount */, + bytes calldata extraData + ) external view returns (uint256) { + uint256 rateBump = _getRateBump(extraData); + return order.makingAmount * takingAmount * (_BASE_POINTS + rateBump) / _BASE_POINTS / order.takingAmount; } - function getTakingAmount(uint256 orderMakingAmount, uint256 orderTakingAmount, bytes calldata auctionDetails) external view returns (uint256) { - uint256 requestedMakingAmount = uint256(bytes32(msg.data[msg.data.length - 0x60:])); - uint256 rateBump = _getRateBump(auctionDetails); - return (orderTakingAmount * requestedMakingAmount * (_BASE_POINTS + rateBump) + orderMakingAmount * _BASE_POINTS - 1) / _BASE_POINTS / orderMakingAmount; + function getTakingAmount( + IOrderMixin.Order calldata order, + bytes calldata /* extension */, + bytes32 /* orderHash */, + address /* taker */, + uint256 makingAmount, + uint256 /* remainingMakingAmount */, + bytes calldata extraData + ) external view returns (uint256) { + uint256 rateBump = _getRateBump(extraData); + return (order.takingAmount * makingAmount * (_BASE_POINTS + rateBump) + order.makingAmount * _BASE_POINTS - 1) / _BASE_POINTS / order.makingAmount; } function _getRateBump(bytes calldata auctionDetails) private view returns (uint256) { @@ -113,13 +128,14 @@ contract SettlementExtension is IPreInteraction, FeeBankCharger { return false; } - function preInteraction( + function postInteraction( IOrderMixin.Order calldata order, - bytes32, + bytes calldata /* extension */, + bytes32 /* orderHash */, address taker, uint256 makingAmount, uint256 takingAmount, - uint256, + uint256 /* remainingMakingAmount */, bytes calldata extraData ) external onlyLimitOrderProtocol { (uint256 resolverFee, address integrator, uint256 integrationFee, bytes calldata whitelist) = _parseFeeData(extraData, order.makingAmount, makingAmount, takingAmount); diff --git a/package.json b/package.json index 88418424..85839a5a 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "dependencies": { "@1inch/delegating": "0.0.21", "@1inch/erc20-pods": "0.0.17", - "@1inch/limit-order-protocol-contract": "4.0.0-prerelease-7", + "@1inch/limit-order-protocol-contract": "4.0.0-prerelease-14", "@1inch/solidity-utils": "2.2.27", "@1inch/st1inch": "2.0.3", "@openzeppelin/contracts": "4.8.2" diff --git a/yarn.lock b/yarn.lock index 9e684922..9360bf27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38,14 +38,14 @@ "@1inch/solidity-utils" "2.2.5" "@openzeppelin/contracts" "4.8.0" -"@1inch/limit-order-protocol-contract@4.0.0-prerelease-7": - version "4.0.0-prerelease-7" - resolved "https://registry.yarnpkg.com/@1inch/limit-order-protocol-contract/-/limit-order-protocol-contract-4.0.0-prerelease-7.tgz#8410a4171641233698f6e5654fa70ca7286a9155" - integrity sha512-ZqT4CoY3INKESq4Hi2f2RJyV3FsqEvHd4mcZql+uotTyy6ZW2e2JN9ocPLruHwOtlaLnhi6zVbtWxK0wwRuF4w== +"@1inch/limit-order-protocol-contract@4.0.0-prerelease-14": + version "4.0.0-prerelease-14" + resolved "https://registry.yarnpkg.com/@1inch/limit-order-protocol-contract/-/limit-order-protocol-contract-4.0.0-prerelease-14.tgz#6f2eb42b13fbfc4fda6cf95271ae2703f58127f2" + integrity sha512-iHY9rDBjCaUyDOPpUcmv66OeM69AObPZgh3w2+mGFQZ3sKudtnG/Tqdzsy7LEbJ1xDCUL0x/OmvllvWi1yqAbA== dependencies: "@1inch/solidity-utils" "2.2.27" "@chainlink/contracts" "0.6.1" - "@openzeppelin/contracts" "4.8.3" + "@openzeppelin/contracts" "4.9.0" "@1inch/solidity-utils@2.2.21": version "2.2.21" @@ -1208,10 +1208,10 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.2.tgz#d815ade0027b50beb9bcca67143c6bcc3e3923d6" integrity sha512-kEUOgPQszC0fSYWpbh2kT94ltOJwj1qfT2DWo+zVttmGmf97JZ99LspePNaeeaLhCImaHVeBbjaQFZQn7+Zc5g== -"@openzeppelin/contracts@4.8.3": - version "4.8.3" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.3.tgz#cbef3146bfc570849405f59cba18235da95a252a" - integrity sha512-bQHV8R9Me8IaJoJ2vPG4rXcL7seB7YVuskr4f+f5RyOStSZetwzkWtoqDMl5erkBJy0lDRUnIR2WIkPiC0GJlg== +"@openzeppelin/contracts@4.9.0": + version "4.9.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.0.tgz#683f33b6598970051bc5f0806fd8660da9e018dd" + integrity sha512-DUP74AFGKlic2sQb/CmgrN2aUPMFGxRrmCTUxLHsiU2RzwWqVuMPZBxiAyvlff6Pea77uylAX6B5x9W6evEbhA== "@openzeppelin/contracts@~4.3.3": version "4.3.3" From 25f2a2f6b6b8ac15d18c9fc29caf6a2ff6667e77 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Fri, 6 Oct 2023 14:13:54 +0400 Subject: [PATCH 06/32] linter --- test/MeasureGas.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/MeasureGas.js b/test/MeasureGas.js index 9b58579d..b9b7b8be 100644 --- a/test/MeasureGas.js +++ b/test/MeasureGas.js @@ -92,7 +92,7 @@ describe('MeasureGas', function () { const auctionStartTime = await time.latest(); const auctionDetails = ethers.utils.solidityPack( - ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0] + ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], ); const order = buildOrder({ @@ -106,7 +106,7 @@ describe('MeasureGas', function () { makingAmountData: settlementExtension.address + trim0x(auctionDetails), takingAmountData: settlementExtension.address + trim0x(auctionDetails), postInteraction: settlementExtension.address + trim0x(ethers.utils.solidityPack( - ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + owner.address.substring(22), 0] + ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + owner.address.substring(22), 0], )), }); @@ -158,7 +158,7 @@ describe('MeasureGas', function () { makerTraits: buildMakerTraits({ allowedSender: settlement.address }), }); orders[i].salt = fusionHashes[i]; - const { r, vs } = compactSignature(await signOrder(orders[i], chainId, swap.address, alice)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(orders[i], chainId, swap.address, alice)); signatures[i] = { r, vs }; } orders[4] = buildOrder({ @@ -170,7 +170,8 @@ describe('MeasureGas', function () { makerTraits: settlement.address, }); orders[4].salt = fusionHashes[4]; - const { r, vs } = compactSignature(await signOrder(orders[4], chainId, swap.address, owner)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(orders[4], chainId, swap.address, owner)); + signatures[4] = { r, vs }; // Encode data for fillingg orders From 8a13cbdd1026d23011bcc2e469bf60802ca2fe9a Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Fri, 6 Oct 2023 14:14:15 +0400 Subject: [PATCH 07/32] use ceilDiv --- contracts/SettlementExtension.sol | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/SettlementExtension.sol b/contracts/SettlementExtension.sol index 5920f849..5dd37535 100644 --- a/contracts/SettlementExtension.sol +++ b/contracts/SettlementExtension.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.19; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "@openzeppelin/contracts/utils/math/Math.sol"; import "@1inch/limit-order-protocol-contract/contracts/interfaces/IPostInteraction.sol"; import "@1inch/limit-order-protocol-contract/contracts/interfaces/IAmountGetter.sol"; import "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol"; @@ -73,7 +74,7 @@ contract SettlementExtension is IPostInteraction, IAmountGetter, FeeBankCharger bytes calldata extraData ) external view returns (uint256) { uint256 rateBump = _getRateBump(extraData); - return (order.takingAmount * makingAmount * (_BASE_POINTS + rateBump) + order.makingAmount * _BASE_POINTS - 1) / _BASE_POINTS / order.makingAmount; + return Math.ceilDiv(order.takingAmount * makingAmount * (_BASE_POINTS + rateBump), _BASE_POINTS * order.makingAmount); } function _getRateBump(bytes calldata auctionDetails) private view returns (uint256) { From 3c76442a82ef4c4d8cf8b033620e86b6dd9bd8a3 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Fri, 6 Oct 2023 14:14:23 +0400 Subject: [PATCH 08/32] reorder internal functions --- contracts/SettlementExtension.sol | 46 +++++++++++++++---------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/contracts/SettlementExtension.sol b/contracts/SettlementExtension.sol index 5dd37535..d03f07de 100644 --- a/contracts/SettlementExtension.sol +++ b/contracts/SettlementExtension.sol @@ -106,29 +106,6 @@ contract SettlementExtension is IPostInteraction, IAmountGetter, FeeBankCharger return (auctionFinishTime - block.timestamp) * currentRateBump / (auctionFinishTime - currentPointTime); } - /// struct WhitelistDetails { - /// bytes4 auctionStartTime; - /// (bytes10,bytes2)[N] resolversAddressesAndTimeDeltas; - /// } - - function _isWhitelisted(bytes calldata whitelist, address resolver) private view returns (bool) { - uint256 allowedTime = uint32(bytes4(whitelist[0:4])); // initially set to auction start time - whitelist = whitelist[4:]; - uint256 whitelistSize = whitelist.length / 12; - uint80 maskedResolverAddress = uint80(uint160(resolver) & _RESOLVER_ADDRESS_MASK); - for (uint256 i = 0; i < whitelistSize; i++) { - uint80 whitelistedAddress = uint80(bytes10(whitelist[:10])); - allowedTime += uint16(bytes2(whitelist[10:12])); // add next time delta - if (maskedResolverAddress == whitelistedAddress) { - return allowedTime <= block.timestamp; - } else if (allowedTime > block.timestamp) { - return false; - } - whitelist = whitelist[12:]; - } - return false; - } - function postInteraction( IOrderMixin.Order calldata order, bytes calldata /* extension */, @@ -176,4 +153,27 @@ contract SettlementExtension is IPostInteraction, IAmountGetter, FeeBankCharger } whitelist = extraData; } + + /// struct WhitelistDetails { + /// bytes4 auctionStartTime; + /// (bytes10,bytes2)[N] resolversAddressesAndTimeDeltas; + /// } + + function _isWhitelisted(bytes calldata whitelist, address resolver) private view returns (bool) { + uint256 allowedTime = uint32(bytes4(whitelist[0:4])); // initially set to auction start time + whitelist = whitelist[4:]; + uint256 whitelistSize = whitelist.length / 12; + uint80 maskedResolverAddress = uint80(uint160(resolver) & _RESOLVER_ADDRESS_MASK); + for (uint256 i = 0; i < whitelistSize; i++) { + uint80 whitelistedAddress = uint80(bytes10(whitelist[:10])); + allowedTime += uint16(bytes2(whitelist[10:12])); // add next time delta + if (maskedResolverAddress == whitelistedAddress) { + return allowedTime <= block.timestamp; + } else if (allowedTime > block.timestamp) { + return false; + } + whitelist = whitelist[12:]; + } + return false; + } } From 53abdbb39c1aa95f7d9d183377f520e9425063b8 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Fri, 6 Oct 2023 18:50:45 +0400 Subject: [PATCH 09/32] round resolver fee down --- contracts/SettlementExtension.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/SettlementExtension.sol b/contracts/SettlementExtension.sol index d03f07de..e08ac8b4 100644 --- a/contracts/SettlementExtension.sol +++ b/contracts/SettlementExtension.sol @@ -142,7 +142,7 @@ contract SettlementExtension is IPostInteraction, IAmountGetter, FeeBankCharger extraData = extraData[1:]; if (feeType & 0x01 == 0x01) { // resolverFee enabled - resolverFee = (_ORDER_FEE_BASE_POINTS * uint256(uint32(bytes4(extraData[:4]))) * actualMakingAmount + orderMakingAmount - 1) / orderMakingAmount; + resolverFee = uint256(uint32(bytes4(extraData[:4]))) * _ORDER_FEE_BASE_POINTS * actualMakingAmount / orderMakingAmount; extraData = extraData[4:]; } if (feeType & 0x02 == 0x02) { From 1fbefae59f30290f009ac8a8ffd81704bcb85699 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 10 Oct 2023 14:04:35 +0300 Subject: [PATCH 10/32] Fix some tests w/o Settlement and WhitelistChecker --- artifacts-v1/LimitOrderProtocolV3.json | 1573 +++++++++++++++++++ artifacts-v1/ResolverV1Mock.json | 76 + artifacts-v1/SettlementV1.json | 199 +++ contracts/mocks/SettlementExtensionMock.sol | 15 + package.json | 1 + test/FeeBank.js | 4 +- test/MeasureGas.js | 362 +++-- test/Settlement.js | 2 +- test/WhitelistChecker.js | 44 +- test/helpers/fixtures.js | 11 +- yarn.lock | 1307 +++++++-------- 11 files changed, 2711 insertions(+), 883 deletions(-) create mode 100644 artifacts-v1/LimitOrderProtocolV3.json create mode 100644 artifacts-v1/ResolverV1Mock.json create mode 100644 artifacts-v1/SettlementV1.json create mode 100644 contracts/mocks/SettlementExtensionMock.sol diff --git a/artifacts-v1/LimitOrderProtocolV3.json b/artifacts-v1/LimitOrderProtocolV3.json new file mode 100644 index 00000000..484da230 --- /dev/null +++ b/artifacts-v1/LimitOrderProtocolV3.json @@ -0,0 +1,1573 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "LimitOrderProtocolV3", + "sourceName": "LimitOrderProtocolV3.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IWETH", + "name": "_weth", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccessDenied", + "type": "error" + }, + { + "inputs": [], + "name": "AdvanceNonceFailed", + "type": "error" + }, + { + "inputs": [], + "name": "AlreadyFilled", + "type": "error" + }, + { + "inputs": [], + "name": "ArbitraryStaticCallFailed", + "type": "error" + }, + { + "inputs": [], + "name": "BadSignature", + "type": "error" + }, + { + "inputs": [], + "name": "ETHTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "EthDepositRejected", + "type": "error" + }, + { + "inputs": [], + "name": "GetAmountCallFailed", + "type": "error" + }, + { + "inputs": [], + "name": "IncorrectDataLength", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidMsgValue", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidatedOrder", + "type": "error" + }, + { + "inputs": [], + "name": "MakingAmountExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "MakingAmountTooLow", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyOneAmountShouldBeZero", + "type": "error" + }, + { + "inputs": [], + "name": "OrderExpired", + "type": "error" + }, + { + "inputs": [], + "name": "PermitLengthTooLow", + "type": "error" + }, + { + "inputs": [], + "name": "PredicateIsNotTrue", + "type": "error" + }, + { + "inputs": [], + "name": "PrivateOrder", + "type": "error" + }, + { + "inputs": [], + "name": "RFQBadSignature", + "type": "error" + }, + { + "inputs": [], + "name": "RFQPrivateOrder", + "type": "error" + }, + { + "inputs": [], + "name": "RFQSwapWithZeroAmount", + "type": "error" + }, + { + "inputs": [], + "name": "RFQZeroTargetIsForbidden", + "type": "error" + }, + { + "inputs": [], + "name": "ReentrancyDetected", + "type": "error" + }, + { + "inputs": [], + "name": "RemainingAmountIsZero", + "type": "error" + }, + { + "inputs": [], + "name": "SafePermitBadLength", + "type": "error" + }, + { + "inputs": [], + "name": "SafeTransferFromFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "success", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "res", + "type": "bytes" + } + ], + "name": "SimulationResults", + "type": "error" + }, + { + "inputs": [], + "name": "SwapWithZeroAmount", + "type": "error" + }, + { + "inputs": [], + "name": "TakingAmountExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "TakingAmountIncreased", + "type": "error" + }, + { + "inputs": [], + "name": "TakingAmountTooHigh", + "type": "error" + }, + { + "inputs": [], + "name": "TransferFromMakerToTakerFailed", + "type": "error" + }, + { + "inputs": [], + "name": "TransferFromTakerToMakerFailed", + "type": "error" + }, + { + "inputs": [], + "name": "UnknownOrder", + "type": "error" + }, + { + "inputs": [], + "name": "WrongAmount", + "type": "error" + }, + { + "inputs": [], + "name": "WrongGetter", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroTargetIsForbidden", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newNonce", + "type": "uint256" + } + ], + "name": "NonceIncreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "orderHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remainingRaw", + "type": "uint256" + } + ], + "name": "OrderCanceled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "orderHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remaining", + "type": "uint256" + } + ], + "name": "OrderFilled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "orderHash", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + } + ], + "name": "OrderFilledRFQ", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "advanceNonce", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offsets", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "and", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "arbitraryStaticCall", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "salt", + "type": "uint256" + }, + { + "internalType": "address", + "name": "makerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "takerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "allowedSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "offsets", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "interactions", + "type": "bytes" + } + ], + "internalType": "struct OrderLib.Order", + "name": "order", + "type": "tuple" + } + ], + "name": "cancelOrder", + "outputs": [ + { + "internalType": "uint256", + "name": "orderRemaining", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "orderHash", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "orderInfo", + "type": "uint256" + } + ], + "name": "cancelOrderRFQ", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "orderInfo", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "additionalMask", + "type": "uint256" + } + ], + "name": "cancelOrderRFQ", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "salt", + "type": "uint256" + }, + { + "internalType": "address", + "name": "makerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "takerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "allowedSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "offsets", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "interactions", + "type": "bytes" + } + ], + "internalType": "struct OrderLib.Order", + "name": "order", + "type": "tuple" + } + ], + "name": "checkPredicate", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "eq", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "salt", + "type": "uint256" + }, + { + "internalType": "address", + "name": "makerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "takerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "allowedSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "offsets", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "interactions", + "type": "bytes" + } + ], + "internalType": "struct OrderLib.Order", + "name": "order", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "interaction", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "skipPermitAndThresholdAmount", + "type": "uint256" + } + ], + "name": "fillOrder", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "internalType": "address", + "name": "makerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "takerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "address", + "name": "allowedSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + } + ], + "internalType": "struct OrderRFQLib.OrderRFQ", + "name": "order", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "flagsAndAmount", + "type": "uint256" + } + ], + "name": "fillOrderRFQ", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "internalType": "address", + "name": "makerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "takerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "address", + "name": "allowedSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + } + ], + "internalType": "struct OrderRFQLib.OrderRFQ", + "name": "order", + "type": "tuple" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "vs", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "flagsAndAmount", + "type": "uint256" + } + ], + "name": "fillOrderRFQCompact", + "outputs": [ + { + "internalType": "uint256", + "name": "filledMakingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "filledTakingAmount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "orderHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "internalType": "address", + "name": "makerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "takerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "address", + "name": "allowedSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + } + ], + "internalType": "struct OrderRFQLib.OrderRFQ", + "name": "order", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "flagsAndAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "fillOrderRFQTo", + "outputs": [ + { + "internalType": "uint256", + "name": "filledMakingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "filledTakingAmount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "orderHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "info", + "type": "uint256" + }, + { + "internalType": "address", + "name": "makerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "takerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "address", + "name": "allowedSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + } + ], + "internalType": "struct OrderRFQLib.OrderRFQ", + "name": "order", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "flagsAndAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "permit", + "type": "bytes" + } + ], + "name": "fillOrderRFQToWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "salt", + "type": "uint256" + }, + { + "internalType": "address", + "name": "makerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "takerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "allowedSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "offsets", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "interactions", + "type": "bytes" + } + ], + "internalType": "struct OrderLib.Order", + "name": "order_", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "interaction", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "skipPermitAndThresholdAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + } + ], + "name": "fillOrderTo", + "outputs": [ + { + "internalType": "uint256", + "name": "actualMakingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualTakingAmount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "orderHash", + "type": "bytes32" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "salt", + "type": "uint256" + }, + { + "internalType": "address", + "name": "makerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "takerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "allowedSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "offsets", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "interactions", + "type": "bytes" + } + ], + "internalType": "struct OrderLib.Order", + "name": "order", + "type": "tuple" + }, + { + "internalType": "bytes", + "name": "signature", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "interaction", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "skipPermitAndThresholdAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "permit", + "type": "bytes" + } + ], + "name": "fillOrderToWithPermit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "gt", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "salt", + "type": "uint256" + }, + { + "internalType": "address", + "name": "makerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "takerAsset", + "type": "address" + }, + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "address", + "name": "allowedSender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "makingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "offsets", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "interactions", + "type": "bytes" + } + ], + "internalType": "struct OrderLib.Order", + "name": "order", + "type": "tuple" + } + ], + "name": "hashOrder", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "increaseNonce", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "maker", + "type": "address" + }, + { + "internalType": "uint256", + "name": "slot", + "type": "uint256" + } + ], + "name": "invalidatorForOrderRFQ", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "lt", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonce", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "makerAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "makerNonce", + "type": "uint256" + } + ], + "name": "nonceEquals", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "offsets", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "or", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "orderHash", + "type": "bytes32" + } + ], + "name": "remaining", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "orderHash", + "type": "bytes32" + } + ], + "name": "remainingRaw", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32[]", + "name": "orderHashes", + "type": "bytes32[]" + } + ], + "name": "remainingsRaw", + "outputs": [ + { + "internalType": "uint256[]", + "name": "", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "simulate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "time", + "type": "uint256" + } + ], + "name": "timestampBelow", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "timeNonceAccount", + "type": "uint256" + } + ], + "name": "timestampBelowAndNonceEquals", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } + ], + "bytecode": "0x6101a06040523480156200001257600080fd5b50604051620042ef380380620042ef833981016040819052620000359162000140565b604080518082018252601a81527f31696e6368204c696d6974204f726465722050726f746f636f6c00000000000060208083019182528351808501855260018152603360f81b908201529151902060e08190527f2a80e1ef1d7842f27f2e6be0972bb708b9a135c38860dbe73c27c3486c34f4de6101008190524660a081815285517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818701819052818801959095526060810193909352608080840192909252308382018190528651808503909201825260c09384019096528051940193909320909252919052610120526001600160a01b03166101408190526101608190526101805262000172565b6000602082840312156200015357600080fd5b81516001600160a01b03811681146200016b57600080fd5b9392505050565b60805160a05160c05160e05161010051610120516101405161016051610180516140db62000214600039600081816125b40152818161268901528181612726015281816128650152818161290201526129ca015260006106370152600081816118f501528181611a1d0152611ab001526000611e9901526000611ee801526000611ec301526000611e1c01526000611e4601526000611e7001526140db6000f3fe6080604052600436106101d15760003560e01c80637e54f092116100f7578063bf15fcd811610095578063cf6fc6e311610064578063cf6fc6e314610585578063d365c695146105cc578063e5d7bde6146105ec578063f0e0d64a146105ff57600080fd5b8063bf15fcd814610510578063bfa7514314610530578063c53a029214610550578063ca4ece221461056557600080fd5b80639570eeee116100d15780639570eeee1461049d578063bc1ed74c146104b0578063bd61951d146104d0578063bddccd35146104f057600080fd5b80637e54f09214610423578063825caba114610450578063942461bb1461047057600080fd5b80635a0998431161016f5780636fe7b0ba1161013e5780636fe7b0ba1461039657806370ae92d2146103b657806370ccbd31146103e3578063742611451461040357600080fd5b80635a0998431461033057806362e238bb1461034357806363592c2b146103565780636c8382501461037657600080fd5b806337e7316f116101ab57806337e7316f146102725780633eca9c0a146102925780634f38e2b8146102c057806356f16124146102e057600080fd5b80632cc2878d146101e55780632d9a56f61461021a5780633644e5151461024f57600080fd5b366101e0576101de61061f565b005b600080fd5b3480156101f157600080fd5b5061020561020036600461351f565b610690565b60405190151581526020015b60405180910390f35b34801561022657600080fd5b5061023a610235366004613551565b6106e7565b60408051928352602083019190915201610211565b34801561025b57600080fd5b50610264610811565b604051908152602001610211565b34801561027e57600080fd5b5061026461028d366004613551565b610820565b6102a56102a036600461370d565b61083a565b60408051938452602084019290925290820152606001610211565b3480156102cc57600080fd5b506102056102db36600461376a565b61085c565b3480156102ec57600080fd5b506102646102fb3660046137b6565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600260209081526040808320938352929052205490565b6102a561033e3660046137e0565b610887565b6102a5610351366004613852565b610a99565b34801561036257600080fd5b5061020561037136600461351f565b421090565b34801561038257600080fd5b50610205610391366004613551565b610ac3565b3480156103a257600080fd5b506102056103b136600461376a565b610af2565b3480156103c257600080fd5b506102646103d13660046138fe565b60006020819052908152604090205481565b3480156103ef57600080fd5b506102a56103fe366004613919565b610b18565b34801561040f57600080fd5b5061020561041e36600461376a565b610b6c565b34801561042f57600080fd5b5061026461043e36600461351f565b60009081526001602052604090205490565b34801561045c57600080fd5b506101de61046b36600461351f565b610bde565b34801561047c57600080fd5b5061049061048b3660046139bc565b610bed565b6040516102119190613a62565b6102a56104ab366004613aa6565b610ca6565b3480156104bc57600080fd5b506102646104cb36600461351f565b610e86565b3480156104dc57600080fd5b506101de6104eb366004613ae3565b610ef4565b3480156104fc57600080fd5b506101de61050b366004613b1d565b610fa2565b34801561051c57600080fd5b5061026461052b366004613ae3565b610fb1565b34801561053c57600080fd5b5061020561054b36600461376a565b610ffc565b34801561055c57600080fd5b506101de61106f565b34801561057157600080fd5b5061020561058036600461376a565b611079565b34801561059157600080fd5b506102056105a03660046137b6565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152602081905260409020541490565b3480156105d857600080fd5b506102a56105e7366004613b3f565b6110a0565b6102a56105fa366004613c30565b611141565b34801561060b57600080fd5b506101de61061a36600461351f565b611d6e565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461068e576040517f1b10b0f900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600060d082901c60a083901c65ffffffffffff16836106ae83421090565b80156106de575073ffffffffffffffffffffffffffffffffffffffff811660009081526020819052604090205482145b95945050505050565b600080336106fb60808501606086016138fe565b73ffffffffffffffffffffffffffffffffffffffff1614610748576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61075183610820565b600081815260016020526040902054925090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82016107bd576040517f41a26a6300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518281526020810184905233917fcbfa7d191838ece7ba4783ca3a30afd316619b7f368094b57ee7ffde9a923db1910160405180910390a26000818152600160208190526040909120559092909150565b600061081b611e02565b905090565b600061083461082d611e02565b8390611f36565b92915050565b600080600061084c8787878733610887565b9250925092509450945094915050565b600080600061086b8585611fd0565b9150915081801561087b57508581115b925050505b9392505050565b6000806000610920610897611e02565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a0180517f74ab4f0cde46aaf927859983f7d04002116dd057d4c4941f6dbfb775c3e31f458252610100822091526040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b90507f40000000000000000000000000000000000000000000000000000000000000008516156109fe577f200000000000000000000000000000000000000000000000000000000000000085161580159061097c575060418614155b156109b3576040517f17c2b1f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c38860600151828989612252565b6109f9576040517f17c2b1f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a44565b610a0e88606001518289896122a7565b610a44576040517f17c2b1f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a4f888686612335565b60408051848152602081018490529295509093507fc3b639f02b125bfa160e50739b8c44eb2d1b6908e2b6d5925c6d770f2ca78127910160405180910390a1955095509592505050565b6000806000610aaf8b8b8b8b8b8b8b8b33611141565b925092509250985098509895505050505050565b6000806000610ad9610ad485612aa9565b611fd0565b91509150818015610aea5750806001145b949350505050565b6000806000610b018585611fd0565b9150915081801561087b5750909414949350505050565b6000806000610b4c85858c6040015173ffffffffffffffffffffffffffffffffffffffff16612ac09092919063ffffffff16565b610b598a8a8a8a8a610887565b9250925092509750975097945050505050565b60008080805b63ffffffff87821c1692508215610bd157600080610b95610ad486868a8c613cf0565b91509150818015610ba65750806001145b15610bb957600195505050505050610880565b50839250610bca9050602082613d49565b9050610b72565b5060009695505050505050565b610bea33826000612adc565b50565b60606000825167ffffffffffffffff811115610c0b57610c0b613586565b604051908082528060200260200182016040528015610c34578160200160208202803683370190505b50905060005b8351811015610c9f5760016000858381518110610c5957610c59613d5c565b6020026020010151815260200190815260200160002054828281518110610c8257610c82613d5c565b602090810291909101015280610c9781613d8b565b915050610c3a565b5092915050565b6000806000610d3f610cb6611e02565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0890180517f74ab4f0cde46aaf927859983f7d04002116dd057d4c4941f6dbfb775c3e31f458252610100822091526040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b90507f4000000000000000000000000000000000000000000000000000000000000000841615610dec577f2000000000000000000000000000000000000000000000000000000000000000841615610ddc57610da18760600151828888612b7d565b610dd7576040517f17c2b1f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e32565b610da18760600151828888612c00565b610dfc8760600151828888612c55565b610e32576040517f17c2b1f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3d878533612335565b60408051848152602081018490529295509093507fc3b639f02b125bfa160e50739b8c44eb2d1b6908e2b6d5925c6d770f2ca78127910160405180910390a19450945094915050565b60008181526001602052604081205480610ecc576040517fb838de9600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610f1e929190613dc3565b600060405180830381855af49150503d8060008114610f59576040519150601f19603f3d011682016040523d82523d6000602084013e610f5e565b606091505b509150915081816040517f1934afc8000000000000000000000000000000000000000000000000000000008152600401610f99929190613df7565b60405180910390fd5b610fad338383612adc565b5050565b6000806000610fc1868686612ccb565b91509150816106de576040517f1f1b8f6100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080805b63ffffffff87821c169250821561106257600080611025610ad486868a8c613cf0565b91509150811580611037575080600114155b1561104a57600095505050505050610880565b5083925061105b9050602082613d49565b9050611002565b5060019695505050505050565b61068e6001611d6e565b60008060006110888585611fd0565b9150915081801561087b575094909410949350505050565b6000808060148410156110df576040517fd9e1c6dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003660006110ee8888612cf9565b9194509250905061111673ffffffffffffffffffffffffffffffffffffffff84168383612ac0565b50505061112a8e8e8e8e8e8e8e8e8e611141565b9250925092509b509b509b98505050505050505050565b6000808073ffffffffffffffffffffffffffffffffffffffff8416611192576040517fb0c4d05f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61119b8c610820565b6000818152600160205260409020548894508793509091508c907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810161120e576040517fecef366400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061122060c0840160a085016138fe565b73ffffffffffffffffffffffffffffffffffffffff161415801561126957503361125060c0840160a085016138fe565b73ffffffffffffffffffffffffffffffffffffffff1614155b156112a0576040517fd4dfdafe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806113cc576112c06112b860808401606085016138fe565b848f8f6122a7565b6112f6576040517f5cd5d23300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060c081013536600061130884612d6e565b915091507f80000000000000000000000000000000000000000000000000000000000000008916600014801561133f575060148110155b156113c55760003660006113538585612cf9565b9194509250905061137b73ffffffffffffffffffffffffffffffffffffffff84168383612ac0565b600088815260016020526040902054156113c1576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505b50506113ef565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff015b60006113fa83612aa9565b905011156114415761140b82610ac3565b611441576040517fb6629c0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b841584150361147b576040517ee2a52200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600003611524578085111561148f578094505b6114ad61149b83612d7c565b8460c00135888660e001358689612d8a565b93507f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff87166114dc8682613e51565b6114e68b87613e51565b111561151e576040517ffb8ae12900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611608565b61154261153083612dc2565b8460e00135878660c001358689612dd0565b9450808511156115975780945061155b61149b83612d7c565b935087841115611597576040517f939c420400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff87166115c48582613e51565b6115ce8a88613e51565b1015611606576040517f481ea39200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b841580611613575083155b1561164a576040517ffba5a27600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84810390508060010160016000858152602001908152602001600020819055508d606001602081019061167d91906138fe565b73ffffffffffffffffffffffffffffffffffffffff167fb9ed0243fdf00f0545c63a0af8850c090d86bb46682baec4bf3c496814fe4f0284836040516116cd929190918252602082015260400190565b60405180910390a260146116e083612de4565b9050106117905760003660006116fd6116f886612de4565b612cf9565b9194509250905073ffffffffffffffffffffffffffffffffffffffff83166396a10e33876117316080890160608a016138fe565b338c8c8a89896040518963ffffffff1660e01b815260040161175a989796959493929190613eb1565b600060405180830381600087803b15801561177457600080fd5b505af1158015611788573d6000803e3d6000fd5b505050505050505b6117c36117a360408401602085016138fe565b6117b360808501606086016138fe565b88886117be87612df2565b612e00565b6117f9576040517f70a03f4800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60148a106118de5760003660006118108e8e612cf9565b92509250925060008373ffffffffffffffffffffffffffffffffffffffff1663ccee33d7338b8b87876040518663ffffffff1660e01b8152600401611859959493929190613f11565b6020604051808303816000875af1158015611878573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189c9190613f4d565b905087811180156118bb57506118b96118b487612dc2565b612e74565b155b80156118d057506118ce6118b487612d7c565b155b156118d9578097505b505050505b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001661192560608401604085016138fe565b73ffffffffffffffffffffffffffffffffffffffff161480156119485750600034115b15611bc95783341015611987576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83341115611a1b57604051600090339061138890348890039084818181858888f193505050503d80600081146119d9576040519150601f19603f3d011682016040523d82523d6000602084013e6119de565b606091505b5050905080611a19576040517fb12d13eb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015611a8357600080fd5b505af1158015611a97573d6000803e3d6000fd5b505073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb915060009050611aed60a08601608087016138fe565b73ffffffffffffffffffffffffffffffffffffffff1614611b1d57611b1860a08501608086016138fe565b611b2d565b611b2d60808501606086016138fe565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018790526044016020604051808303816000875af1158015611b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc39190613f66565b50611ca7565b3415611c01576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c71611c1460608401604085016138fe565b336000611c2760a08701608088016138fe565b73ffffffffffffffffffffffffffffffffffffffff1614611c5757611c5260a08601608087016138fe565b611c67565b611c6760808601606087016138fe565b876117be87612ee9565b611ca7576040517f478a520500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6014611cb283612ef7565b905010611d5d576000366000611cca6116f886612ef7565b9194509250905073ffffffffffffffffffffffffffffffffffffffff8316633504ed6287611cfe6080890160608a016138fe565b338c8c8a89896040518963ffffffff1660e01b8152600401611d27989796959493929190613eb1565b600060405180830381600087803b158015611d4157600080fd5b505af1158015611d55573d6000803e3d6000fd5b505050505050505b505099509950999650505050505050565b801580611d7b575060ff81115b15611db2576040517fbd71636d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600081815260208181526040918290208054850190819055825181815292519093927ffc69110dd11eb791755e4abd6b7d281bae236de95736d38a23782814be5e10db92908290030190a25050565b60003073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015611e6857507f000000000000000000000000000000000000000000000000000000000000000046145b15611e9257507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60003681611f48610120860186613f88565b60405191935091507f0a244ca8a150ac294c14fcff9277051ced9a5b23e966a0ff0522e989da23116c908284823782812061014082015261012087602083013790815261016090206040517f19010000000000000000000000000000000000000000000000000000000000008152600281019590955260228501525050604290912092915050565b6000806000611fdf8585612f05565b60e01c90506000611ff286866004612f48565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffd33d7873820161204457600161202682610690565b612031576000612034565b60015b90945060ff16925061224b915050565b63bf15fcd882101561213e57636fe7b0ba8210156120cc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0c71d488201612095576001612026826102db89896064612f92565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff9ca6d3d582016120c757600161202682421090565b612239565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff90184f468201612105576001612026826103b189896064612f92565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff8bd9eebb82016120c75760016120268261041e89896064612f92565b63ca4ece228210156121c7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffff40ea0328820161218e5760016121838261052b89896064612f92565b93509350505061224b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff4058aebd82016120c75760016120268261054b89896064612f92565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff35b131de82016122005760016120268261058089896064612f92565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff3090391d8201612239576001612026826105a089896024612f48565b612244308787612ccb565b9350935050505b9250929050565b600080631626ba7e60e01b905060405181815285600482015260406024820152836044820152838560648301376020600085606401838a5afa1561229d5760203d1460005183141692505b5050949350505050565b600073ffffffffffffffffffffffffffffffffffffffff85166122cc57506000610aea565b60408214806122db5750604182145b801561231c57508473ffffffffffffffffffffffffffffffffffffffff16612304858585612fdb565b73ffffffffffffffffffffffffffffffffffffffff16145b1561232957506001610aea565b6106de85858585612252565b60008073ffffffffffffffffffffffffffffffffffffffff8316612385576040517f692e45e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6060850151608086015173ffffffffffffffffffffffffffffffffffffffff16158015906123cd5750608086015173ffffffffffffffffffffffffffffffffffffffff163314155b15612404576040517fe8c6632100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855167ffffffffffffffff604082901c16801580159061242357508042115b1561245a576040517fc56873ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61246683836000612adc565b505060a086015160c08701517f0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff871660008190036124a95782955081945061256b565b7f8000000000000000000000000000000000000000000000000000000000000000881615612520578281111561250b576040517faa34b69600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8095506125198383886130a9565b945061256b565b8181111561255a576040517f7f902a9300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8094506125688383876130d7565b95505b505050826000148061257b575081155b156125b2576040517f07b6e79f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff1614801561263257507f1000000000000000000000000000000000000000000000000000000000000000851615155b1561283c576040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152306024830152604482018590527f000000000000000000000000000000000000000000000000000000000000000016906323b872dd906064016020604051808303816000875af11580156126d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f69190613f66565b506040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018490527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561277f57600080fd5b505af1158015612793573d6000803e3d6000fd5b5050505060008473ffffffffffffffffffffffffffffffffffffffff168461138890604051600060405180830381858888f193505050503d80600081146127f6576040519150601f19603f3d011682016040523d82523d6000602084013e6127fb565b606091505b5050905080612836576040517fb12d13eb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50612863565b60208601516128639073ffffffffffffffffffffffffffffffffffffffff168286866130e4565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff161480156128c25750600034115b15612a4157813414612900576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b15801561296857600080fd5b505af115801561297c573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018790527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb925060440190506020604051808303816000875af1158015612a17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3b9190613f66565b50612aa0565b3415612a79576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040860151612aa09073ffffffffffffffffffffffffffffffffffffffff163383856130e4565b50935093915050565b366000612ab7836004613181565b91509150915091565b612acb8383836131dc565b612ad757612ad7613282565b505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020908152604080832066ffffffffffffff600887901c16808552928190529220549091600160ff86161b841791808316839003612b64576040517ff71fbda200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000938452602091909152604090922091179055505050565b600080631626ba7e60e01b905060405181815285600482015260406024820152604160448201528460648201527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841660848201528360ff1c601b0160a48201536020600060a5838a5afa1561229d5750600051143d6020141695945050505050565b600080631626ba7e60e01b905060405181815285600482015260406024820152604060448201528460648201528360848201526020600060a4838a5afa1561229d5750600051143d6020141695945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8516612c7a57506000610aea565b8473ffffffffffffffffffffffffffffffffffffffff16612c9c85858561328e565b73ffffffffffffffffffffffffffffffffffffffff1603612cbf57506001610aea565b6106de85858585612c00565b60008060405183858237602060008583895afa3d602014169250508115612cf157506000515b935093915050565b600036816014841015612d38576040517fef356d7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050813560601c926014909201917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec90910190565b366000612ab7836005613181565b366000612ab7836003613181565b6000868103612da557612d9e8685876130a9565b9050612db7565b612db488888888888888613316565b90505b979650505050505050565b366000612ab7836002613181565b6000868103612da557612d9e8487876130d7565b366000612ab7836006613181565b366000612ab7836000613181565b6040517f23b872dd000000000000000000000000000000000000000000000000000000008082526004820187905260248201869052604482018590526000918385606483013760206000856064018360008d5af19050600160005114601f3d11163d15178116925050509695505050505050565b6000600182148015610880575082826000818110612e9457612e94613d5c565b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f7800000000000000000000000000000000000000000000000000000000000000149392505050565b366000612ab7836001613181565b366000612ab7836007613181565b60006004821015612f42576040517fef356d7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50503590565b600060208201831015612f87576040517fef356d7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509190910135919050565b36600082841015612fcf576040517fef356d7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50509182019291900390565b60006040518260418114612ffa57604081146130145760009150613055565b604085013560001a60208301526040856040840137613055565b60208501358060ff1c601b01602084015260208660408501377f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660608301525b5080156130a1577f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1606082015110156130a157848152600080526020600060808360015afa5060005191505b509392505050565b6000836001816130b98686613e51565b6130c39190613d49565b6130cd9190613fed565b610aea9190614000565b6000826130cd8584613e51565b60006323b872dd60e01b905060006040518281528560048201528460248201528360448201526020600060648360008b5af19150508015613142573d801561313857600160005114601f3d11169150613140565b6000873b1191505b505b80613179576040517ff405907100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b3660008060058460078111156131995761319961403b565b901b90506131ab610120860186613f88565b6131d09161010088013580851c63ffffffff9081169360209290921b861c1691613cf0565b92509250509250929050565b600060e082900361321a57613213847fd505accf0000000000000000000000000000000000000000000000000000000085856134cd565b9050610880565b61010082900361325057613213847f8fcbaf0c0000000000000000000000000000000000000000000000000000000085856134cd565b6040517f6827585700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040513d6000823e3d81fd5b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82167f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a18110156130a1576040518581528360ff1c601b016020820152846040820152816060820152600080526020600060808360015afa505060005195945050505050565b600060018790036133a25761332b8888612e74565b1561337057858514613369576040517f49986e7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5082612db7565b6040517fbec74c8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003660006133b18b8b612cf9565b9250925092506000808473ffffffffffffffffffffffffffffffffffffffff1684848c8b8b6040516020016133ea95949392919061406a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261342291614089565b600060405180830381855afa9150503d806000811461345d576040519150601f19603f3d011682016040523d82523d6000602084013e613462565b606091505b509150915081158061347657508051602014155b156134ad576040517f110b8e7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808060200190518101906134c19190613f4d565b95505050505050612db7565b6000816004016040518581528385600483013760206000838360008b5af1925050508015610aea573d801561350e57600160005114601f3d11169150613516565b6000863b1191505b50949350505050565b60006020828403121561353157600080fd5b5035919050565b6000610140828403121561354b57600080fd5b50919050565b60006020828403121561356357600080fd5b813567ffffffffffffffff81111561357a57600080fd5b610aea84828501613538565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156135fc576135fc613586565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461362857600080fd5b919050565b600060e0828403121561363f57600080fd5b60405160e0810181811067ffffffffffffffff8211171561366257613662613586565b6040528235815290508061367860208401613604565b602082015261368960408401613604565b604082015261369a60608401613604565b60608201526136ab60808401613604565b608082015260a083013560a082015260c083013560c08201525092915050565b60008083601f8401126136dd57600080fd5b50813567ffffffffffffffff8111156136f557600080fd5b60208301915083602082850101111561224b57600080fd5b600080600080610120858703121561372457600080fd5b61372e868661362d565b935060e085013567ffffffffffffffff81111561374a57600080fd5b613756878288016136cb565b959890975094956101000135949350505050565b60008060006040848603121561377f57600080fd5b83359250602084013567ffffffffffffffff81111561379d57600080fd5b6137a9868287016136cb565b9497909650939450505050565b600080604083850312156137c957600080fd5b6137d283613604565b946020939093013593505050565b600080600080600061014086880312156137f957600080fd5b613803878761362d565b945060e086013567ffffffffffffffff81111561381f57600080fd5b61382b888289016136cb565b90955093505061010086013591506138466101208701613604565b90509295509295909350565b60008060008060008060008060c0898b03121561386e57600080fd5b883567ffffffffffffffff8082111561388657600080fd5b6138928c838d01613538565b995060208b01359150808211156138a857600080fd5b6138b48c838d016136cb565b909950975060408b01359150808211156138cd57600080fd5b506138da8b828c016136cb565b999c989b5096999698976060880135976080810135975060a0013595509350505050565b60006020828403121561391057600080fd5b61088082613604565b6000806000806000806000610160888a03121561393557600080fd5b61393f898961362d565b965060e088013567ffffffffffffffff8082111561395c57600080fd5b6139688b838c016136cb565b90985096506101008a013595508691506139856101208b01613604565b94506101408a013591508082111561399c57600080fd5b506139a98a828b016136cb565b989b979a50959850939692959293505050565b600060208083850312156139cf57600080fd5b823567ffffffffffffffff808211156139e757600080fd5b818501915085601f8301126139fb57600080fd5b813581811115613a0d57613a0d613586565b8060051b9150613a1e8483016135b5565b8181529183018401918481019088841115613a3857600080fd5b938501935b83851015613a5657843582529385019390850190613a3d565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613a9a57835183529284019291840191600101613a7e565b50909695505050505050565b6000806000806101408587031215613abd57600080fd5b613ac7868661362d565b9660e08601359650610100860135956101200135945092505050565b600080600060408486031215613af857600080fd5b613b0184613604565b9250602084013567ffffffffffffffff81111561379d57600080fd5b60008060408385031215613b3057600080fd5b50508035926020909101359150565b60008060008060008060008060008060006101008c8e031215613b6157600080fd5b67ffffffffffffffff808d351115613b7857600080fd5b613b858e8e358f01613538565b9b508060208e01351115613b9857600080fd5b613ba88e60208f01358f016136cb565b909b50995060408d0135811015613bbe57600080fd5b613bce8e60408f01358f016136cb565b909950975060608d0135965060808d0135955060a08d01359450613bf460c08e01613604565b93508060e08e01351115613c0757600080fd5b50613c188d60e08e01358e016136cb565b81935080925050509295989b509295989b9093969950565b600080600080600080600080600060e08a8c031215613c4e57600080fd5b893567ffffffffffffffff80821115613c6657600080fd5b613c728d838e01613538565b9a5060208c0135915080821115613c8857600080fd5b613c948d838e016136cb565b909a50985060408c0135915080821115613cad57600080fd5b50613cba8c828d016136cb565b90975095505060608a0135935060808a0135925060a08a01359150613ce160c08b01613604565b90509295985092959850929598565b60008085851115613d0057600080fd5b83861115613d0d57600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561083457610834613d1a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dbc57613dbc613d1a565b5060010190565b8183823760009101908152919050565b60005b83811015613dee578181015183820152602001613dd6565b50506000910152565b82151581526040602082015260008251806040840152613e1e816060850160208701613dd3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b808202811582820484141761083457610834613d1a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b888152600073ffffffffffffffffffffffffffffffffffffffff808a1660208401528089166040840152508660608301528560808301528460a083015260e060c0830152613f0360e083018486613e68565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152846020820152836040820152608060608201526000612db7608083018486613e68565b600060208284031215613f5f57600080fd5b5051919050565b600060208284031215613f7857600080fd5b8151801515811461088057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613fbd57600080fd5b83018035915067ffffffffffffffff821115613fd857600080fd5b60200191503681900382131561224b57600080fd5b8181038181111561083457610834613d1a565b600082614036577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8486823790930191825260208201526040810191909152606001919050565b6000825161409b818460208701613dd3565b919091019291505056fea264697066735822122057a4b2f141b321f193881112c3a0d0e5e22be10b804ee6bf7d45b729036daf8964736f6c63430008110033", + "deployedBytecode": "0x6080604052600436106101d15760003560e01c80637e54f092116100f7578063bf15fcd811610095578063cf6fc6e311610064578063cf6fc6e314610585578063d365c695146105cc578063e5d7bde6146105ec578063f0e0d64a146105ff57600080fd5b8063bf15fcd814610510578063bfa7514314610530578063c53a029214610550578063ca4ece221461056557600080fd5b80639570eeee116100d15780639570eeee1461049d578063bc1ed74c146104b0578063bd61951d146104d0578063bddccd35146104f057600080fd5b80637e54f09214610423578063825caba114610450578063942461bb1461047057600080fd5b80635a0998431161016f5780636fe7b0ba1161013e5780636fe7b0ba1461039657806370ae92d2146103b657806370ccbd31146103e3578063742611451461040357600080fd5b80635a0998431461033057806362e238bb1461034357806363592c2b146103565780636c8382501461037657600080fd5b806337e7316f116101ab57806337e7316f146102725780633eca9c0a146102925780634f38e2b8146102c057806356f16124146102e057600080fd5b80632cc2878d146101e55780632d9a56f61461021a5780633644e5151461024f57600080fd5b366101e0576101de61061f565b005b600080fd5b3480156101f157600080fd5b5061020561020036600461351f565b610690565b60405190151581526020015b60405180910390f35b34801561022657600080fd5b5061023a610235366004613551565b6106e7565b60408051928352602083019190915201610211565b34801561025b57600080fd5b50610264610811565b604051908152602001610211565b34801561027e57600080fd5b5061026461028d366004613551565b610820565b6102a56102a036600461370d565b61083a565b60408051938452602084019290925290820152606001610211565b3480156102cc57600080fd5b506102056102db36600461376a565b61085c565b3480156102ec57600080fd5b506102646102fb3660046137b6565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152600260209081526040808320938352929052205490565b6102a561033e3660046137e0565b610887565b6102a5610351366004613852565b610a99565b34801561036257600080fd5b5061020561037136600461351f565b421090565b34801561038257600080fd5b50610205610391366004613551565b610ac3565b3480156103a257600080fd5b506102056103b136600461376a565b610af2565b3480156103c257600080fd5b506102646103d13660046138fe565b60006020819052908152604090205481565b3480156103ef57600080fd5b506102a56103fe366004613919565b610b18565b34801561040f57600080fd5b5061020561041e36600461376a565b610b6c565b34801561042f57600080fd5b5061026461043e36600461351f565b60009081526001602052604090205490565b34801561045c57600080fd5b506101de61046b36600461351f565b610bde565b34801561047c57600080fd5b5061049061048b3660046139bc565b610bed565b6040516102119190613a62565b6102a56104ab366004613aa6565b610ca6565b3480156104bc57600080fd5b506102646104cb36600461351f565b610e86565b3480156104dc57600080fd5b506101de6104eb366004613ae3565b610ef4565b3480156104fc57600080fd5b506101de61050b366004613b1d565b610fa2565b34801561051c57600080fd5b5061026461052b366004613ae3565b610fb1565b34801561053c57600080fd5b5061020561054b36600461376a565b610ffc565b34801561055c57600080fd5b506101de61106f565b34801561057157600080fd5b5061020561058036600461376a565b611079565b34801561059157600080fd5b506102056105a03660046137b6565b73ffffffffffffffffffffffffffffffffffffffff919091166000908152602081905260409020541490565b3480156105d857600080fd5b506102a56105e7366004613b3f565b6110a0565b6102a56105fa366004613c30565b611141565b34801561060b57600080fd5b506101de61061a36600461351f565b611d6e565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461068e576040517f1b10b0f900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b600060d082901c60a083901c65ffffffffffff16836106ae83421090565b80156106de575073ffffffffffffffffffffffffffffffffffffffff811660009081526020819052604090205482145b95945050505050565b600080336106fb60808501606086016138fe565b73ffffffffffffffffffffffffffffffffffffffff1614610748576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61075183610820565b600081815260016020526040902054925090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82016107bd576040517f41a26a6300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518281526020810184905233917fcbfa7d191838ece7ba4783ca3a30afd316619b7f368094b57ee7ffde9a923db1910160405180910390a26000818152600160208190526040909120559092909150565b600061081b611e02565b905090565b600061083461082d611e02565b8390611f36565b92915050565b600080600061084c8787878733610887565b9250925092509450945094915050565b600080600061086b8585611fd0565b9150915081801561087b57508581115b925050505b9392505050565b6000806000610920610897611e02565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08a0180517f74ab4f0cde46aaf927859983f7d04002116dd057d4c4941f6dbfb775c3e31f458252610100822091526040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b90507f40000000000000000000000000000000000000000000000000000000000000008516156109fe577f200000000000000000000000000000000000000000000000000000000000000085161580159061097c575060418614155b156109b3576040517f17c2b1f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6109c38860600151828989612252565b6109f9576040517f17c2b1f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a44565b610a0e88606001518289896122a7565b610a44576040517f17c2b1f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a4f888686612335565b60408051848152602081018490529295509093507fc3b639f02b125bfa160e50739b8c44eb2d1b6908e2b6d5925c6d770f2ca78127910160405180910390a1955095509592505050565b6000806000610aaf8b8b8b8b8b8b8b8b33611141565b925092509250985098509895505050505050565b6000806000610ad9610ad485612aa9565b611fd0565b91509150818015610aea5750806001145b949350505050565b6000806000610b018585611fd0565b9150915081801561087b5750909414949350505050565b6000806000610b4c85858c6040015173ffffffffffffffffffffffffffffffffffffffff16612ac09092919063ffffffff16565b610b598a8a8a8a8a610887565b9250925092509750975097945050505050565b60008080805b63ffffffff87821c1692508215610bd157600080610b95610ad486868a8c613cf0565b91509150818015610ba65750806001145b15610bb957600195505050505050610880565b50839250610bca9050602082613d49565b9050610b72565b5060009695505050505050565b610bea33826000612adc565b50565b60606000825167ffffffffffffffff811115610c0b57610c0b613586565b604051908082528060200260200182016040528015610c34578160200160208202803683370190505b50905060005b8351811015610c9f5760016000858381518110610c5957610c59613d5c565b6020026020010151815260200190815260200160002054828281518110610c8257610c82613d5c565b602090810291909101015280610c9781613d8b565b915050610c3a565b5092915050565b6000806000610d3f610cb6611e02565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0890180517f74ab4f0cde46aaf927859983f7d04002116dd057d4c4941f6dbfb775c3e31f458252610100822091526040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b90507f4000000000000000000000000000000000000000000000000000000000000000841615610dec577f2000000000000000000000000000000000000000000000000000000000000000841615610ddc57610da18760600151828888612b7d565b610dd7576040517f17c2b1f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e32565b610da18760600151828888612c00565b610dfc8760600151828888612c55565b610e32576040517f17c2b1f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e3d878533612335565b60408051848152602081018490529295509093507fc3b639f02b125bfa160e50739b8c44eb2d1b6908e2b6d5925c6d770f2ca78127910160405180910390a19450945094915050565b60008181526001602052604081205480610ecc576040517fb838de9600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0192915050565b6000808473ffffffffffffffffffffffffffffffffffffffff168484604051610f1e929190613dc3565b600060405180830381855af49150503d8060008114610f59576040519150601f19603f3d011682016040523d82523d6000602084013e610f5e565b606091505b509150915081816040517f1934afc8000000000000000000000000000000000000000000000000000000008152600401610f99929190613df7565b60405180910390fd5b610fad338383612adc565b5050565b6000806000610fc1868686612ccb565b91509150816106de576040517f1f1b8f6100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008080805b63ffffffff87821c169250821561106257600080611025610ad486868a8c613cf0565b91509150811580611037575080600114155b1561104a57600095505050505050610880565b5083925061105b9050602082613d49565b9050611002565b5060019695505050505050565b61068e6001611d6e565b60008060006110888585611fd0565b9150915081801561087b575094909410949350505050565b6000808060148410156110df576040517fd9e1c6dc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003660006110ee8888612cf9565b9194509250905061111673ffffffffffffffffffffffffffffffffffffffff84168383612ac0565b50505061112a8e8e8e8e8e8e8e8e8e611141565b9250925092509b509b509b98505050505050505050565b6000808073ffffffffffffffffffffffffffffffffffffffff8416611192576040517fb0c4d05f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61119b8c610820565b6000818152600160205260409020548894508793509091508c907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810161120e576040517fecef366400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061122060c0840160a085016138fe565b73ffffffffffffffffffffffffffffffffffffffff161415801561126957503361125060c0840160a085016138fe565b73ffffffffffffffffffffffffffffffffffffffff1614155b156112a0576040517fd4dfdafe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806113cc576112c06112b860808401606085016138fe565b848f8f6122a7565b6112f6576040517f5cd5d23300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060c081013536600061130884612d6e565b915091507f80000000000000000000000000000000000000000000000000000000000000008916600014801561133f575060148110155b156113c55760003660006113538585612cf9565b9194509250905061137b73ffffffffffffffffffffffffffffffffffffffff84168383612ac0565b600088815260016020526040902054156113c1576040517fc5f2be5100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505b50506113ef565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff015b60006113fa83612aa9565b905011156114415761140b82610ac3565b611441576040517fb6629c0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b841584150361147b576040517ee2a52200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600003611524578085111561148f578094505b6114ad61149b83612d7c565b8460c00135888660e001358689612d8a565b93507f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff87166114dc8682613e51565b6114e68b87613e51565b111561151e576040517ffb8ae12900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50611608565b61154261153083612dc2565b8460e00135878660c001358689612dd0565b9450808511156115975780945061155b61149b83612d7c565b935087841115611597576040517f939c420400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff87166115c48582613e51565b6115ce8a88613e51565b1015611606576040517f481ea39200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b841580611613575083155b1561164a576040517ffba5a27600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84810390508060010160016000858152602001908152602001600020819055508d606001602081019061167d91906138fe565b73ffffffffffffffffffffffffffffffffffffffff167fb9ed0243fdf00f0545c63a0af8850c090d86bb46682baec4bf3c496814fe4f0284836040516116cd929190918252602082015260400190565b60405180910390a260146116e083612de4565b9050106117905760003660006116fd6116f886612de4565b612cf9565b9194509250905073ffffffffffffffffffffffffffffffffffffffff83166396a10e33876117316080890160608a016138fe565b338c8c8a89896040518963ffffffff1660e01b815260040161175a989796959493929190613eb1565b600060405180830381600087803b15801561177457600080fd5b505af1158015611788573d6000803e3d6000fd5b505050505050505b6117c36117a360408401602085016138fe565b6117b360808501606086016138fe565b88886117be87612df2565b612e00565b6117f9576040517f70a03f4800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60148a106118de5760003660006118108e8e612cf9565b92509250925060008373ffffffffffffffffffffffffffffffffffffffff1663ccee33d7338b8b87876040518663ffffffff1660e01b8152600401611859959493929190613f11565b6020604051808303816000875af1158015611878573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189c9190613f4d565b905087811180156118bb57506118b96118b487612dc2565b612e74565b155b80156118d057506118ce6118b487612d7c565b155b156118d9578097505b505050505b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001661192560608401604085016138fe565b73ffffffffffffffffffffffffffffffffffffffff161480156119485750600034115b15611bc95783341015611987576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83341115611a1b57604051600090339061138890348890039084818181858888f193505050503d80600081146119d9576040519150601f19603f3d011682016040523d82523d6000602084013e6119de565b606091505b5050905080611a19576040517fb12d13eb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015611a8357600080fd5b505af1158015611a97573d6000803e3d6000fd5b505073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016925063a9059cbb915060009050611aed60a08601608087016138fe565b73ffffffffffffffffffffffffffffffffffffffff1614611b1d57611b1860a08501608086016138fe565b611b2d565b611b2d60808501606086016138fe565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602481018790526044016020604051808303816000875af1158015611b9f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bc39190613f66565b50611ca7565b3415611c01576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611c71611c1460608401604085016138fe565b336000611c2760a08701608088016138fe565b73ffffffffffffffffffffffffffffffffffffffff1614611c5757611c5260a08601608087016138fe565b611c67565b611c6760808601606087016138fe565b876117be87612ee9565b611ca7576040517f478a520500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6014611cb283612ef7565b905010611d5d576000366000611cca6116f886612ef7565b9194509250905073ffffffffffffffffffffffffffffffffffffffff8316633504ed6287611cfe6080890160608a016138fe565b338c8c8a89896040518963ffffffff1660e01b8152600401611d27989796959493929190613eb1565b600060405180830381600087803b158015611d4157600080fd5b505af1158015611d55573d6000803e3d6000fd5b505050505050505b505099509950999650505050505050565b801580611d7b575060ff81115b15611db2576040517fbd71636d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b33600081815260208181526040918290208054850190819055825181815292519093927ffc69110dd11eb791755e4abd6b7d281bae236de95736d38a23782814be5e10db92908290030190a25050565b60003073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016148015611e6857507f000000000000000000000000000000000000000000000000000000000000000046145b15611e9257507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b60003681611f48610120860186613f88565b60405191935091507f0a244ca8a150ac294c14fcff9277051ced9a5b23e966a0ff0522e989da23116c908284823782812061014082015261012087602083013790815261016090206040517f19010000000000000000000000000000000000000000000000000000000000008152600281019590955260228501525050604290912092915050565b6000806000611fdf8585612f05565b60e01c90506000611ff286866004612f48565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffd33d7873820161204457600161202682610690565b612031576000612034565b60015b90945060ff16925061224b915050565b63bf15fcd882101561213e57636fe7b0ba8210156120cc577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffb0c71d488201612095576001612026826102db89896064612f92565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff9ca6d3d582016120c757600161202682421090565b612239565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff90184f468201612105576001612026826103b189896064612f92565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff8bd9eebb82016120c75760016120268261041e89896064612f92565b63ca4ece228210156121c7577fffffffffffffffffffffffffffffffffffffffffffffffffffffffff40ea0328820161218e5760016121838261052b89896064612f92565b93509350505061224b565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff4058aebd82016120c75760016120268261054b89896064612f92565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff35b131de82016122005760016120268261058089896064612f92565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff3090391d8201612239576001612026826105a089896024612f48565b612244308787612ccb565b9350935050505b9250929050565b600080631626ba7e60e01b905060405181815285600482015260406024820152836044820152838560648301376020600085606401838a5afa1561229d5760203d1460005183141692505b5050949350505050565b600073ffffffffffffffffffffffffffffffffffffffff85166122cc57506000610aea565b60408214806122db5750604182145b801561231c57508473ffffffffffffffffffffffffffffffffffffffff16612304858585612fdb565b73ffffffffffffffffffffffffffffffffffffffff16145b1561232957506001610aea565b6106de85858585612252565b60008073ffffffffffffffffffffffffffffffffffffffff8316612385576040517f692e45e000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6060850151608086015173ffffffffffffffffffffffffffffffffffffffff16158015906123cd5750608086015173ffffffffffffffffffffffffffffffffffffffff163314155b15612404576040517fe8c6632100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b855167ffffffffffffffff604082901c16801580159061242357508042115b1561245a576040517fc56873ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61246683836000612adc565b505060a086015160c08701517f0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff871660008190036124a95782955081945061256b565b7f8000000000000000000000000000000000000000000000000000000000000000881615612520578281111561250b576040517faa34b69600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8095506125198383886130a9565b945061256b565b8181111561255a576040517f7f902a9300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8094506125688383876130d7565b95505b505050826000148061257b575081155b156125b2576040517f07b6e79f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16866020015173ffffffffffffffffffffffffffffffffffffffff1614801561263257507f1000000000000000000000000000000000000000000000000000000000000000851615155b1561283c576040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152306024830152604482018590527f000000000000000000000000000000000000000000000000000000000000000016906323b872dd906064016020604051808303816000875af11580156126d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126f69190613f66565b506040517f2e1a7d4d000000000000000000000000000000000000000000000000000000008152600481018490527f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b15801561277f57600080fd5b505af1158015612793573d6000803e3d6000fd5b5050505060008473ffffffffffffffffffffffffffffffffffffffff168461138890604051600060405180830381858888f193505050503d80600081146127f6576040519150601f19603f3d011682016040523d82523d6000602084013e6127fb565b606091505b5050905080612836576040517fb12d13eb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50612863565b60208601516128639073ffffffffffffffffffffffffffffffffffffffff168286866130e4565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16866040015173ffffffffffffffffffffffffffffffffffffffff161480156128c25750600034115b15612a4157813414612900576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b15801561296857600080fd5b505af115801561297c573d6000803e3d6000fd5b50506040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8581166004830152602482018790527f000000000000000000000000000000000000000000000000000000000000000016935063a9059cbb925060440190506020604051808303816000875af1158015612a17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a3b9190613f66565b50612aa0565b3415612a79576040517f1841b4e100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040860151612aa09073ffffffffffffffffffffffffffffffffffffffff163383856130e4565b50935093915050565b366000612ab7836004613181565b91509150915091565b612acb8383836131dc565b612ad757612ad7613282565b505050565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260026020908152604080832066ffffffffffffff600887901c16808552928190529220549091600160ff86161b841791808316839003612b64576040517ff71fbda200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000938452602091909152604090922091179055505050565b600080631626ba7e60e01b905060405181815285600482015260406024820152604160448201528460648201527f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff841660848201528360ff1c601b0160a48201536020600060a5838a5afa1561229d5750600051143d6020141695945050505050565b600080631626ba7e60e01b905060405181815285600482015260406024820152604060448201528460648201528360848201526020600060a4838a5afa1561229d5750600051143d6020141695945050505050565b600073ffffffffffffffffffffffffffffffffffffffff8516612c7a57506000610aea565b8473ffffffffffffffffffffffffffffffffffffffff16612c9c85858561328e565b73ffffffffffffffffffffffffffffffffffffffff1603612cbf57506001610aea565b6106de85858585612c00565b60008060405183858237602060008583895afa3d602014169250508115612cf157506000515b935093915050565b600036816014841015612d38576040517fef356d7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050813560601c926014909201917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec90910190565b366000612ab7836005613181565b366000612ab7836003613181565b6000868103612da557612d9e8685876130a9565b9050612db7565b612db488888888888888613316565b90505b979650505050505050565b366000612ab7836002613181565b6000868103612da557612d9e8487876130d7565b366000612ab7836006613181565b366000612ab7836000613181565b6040517f23b872dd000000000000000000000000000000000000000000000000000000008082526004820187905260248201869052604482018590526000918385606483013760206000856064018360008d5af19050600160005114601f3d11163d15178116925050509695505050505050565b6000600182148015610880575082826000818110612e9457612e94613d5c565b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f7800000000000000000000000000000000000000000000000000000000000000149392505050565b366000612ab7836001613181565b366000612ab7836007613181565b60006004821015612f42576040517fef356d7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50503590565b600060208201831015612f87576040517fef356d7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b509190910135919050565b36600082841015612fcf576040517fef356d7a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50509182019291900390565b60006040518260418114612ffa57604081146130145760009150613055565b604085013560001a60208301526040856040840137613055565b60208501358060ff1c601b01602084015260208660408501377f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660608301525b5080156130a1577f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1606082015110156130a157848152600080526020600060808360015afa5060005191505b509392505050565b6000836001816130b98686613e51565b6130c39190613d49565b6130cd9190613fed565b610aea9190614000565b6000826130cd8584613e51565b60006323b872dd60e01b905060006040518281528560048201528460248201528360448201526020600060648360008b5af19150508015613142573d801561313857600160005114601f3d11169150613140565b6000873b1191505b505b80613179576040517ff405907100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b3660008060058460078111156131995761319961403b565b901b90506131ab610120860186613f88565b6131d09161010088013580851c63ffffffff9081169360209290921b861c1691613cf0565b92509250509250929050565b600060e082900361321a57613213847fd505accf0000000000000000000000000000000000000000000000000000000085856134cd565b9050610880565b61010082900361325057613213847f8fcbaf0c0000000000000000000000000000000000000000000000000000000085856134cd565b6040517f6827585700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040513d6000823e3d81fd5b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82167f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a18110156130a1576040518581528360ff1c601b016020820152846040820152816060820152600080526020600060808360015afa505060005195945050505050565b600060018790036133a25761332b8888612e74565b1561337057858514613369576040517f49986e7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5082612db7565b6040517fbec74c8500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003660006133b18b8b612cf9565b9250925092506000808473ffffffffffffffffffffffffffffffffffffffff1684848c8b8b6040516020016133ea95949392919061406a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905261342291614089565b600060405180830381855afa9150503d806000811461345d576040519150601f19603f3d011682016040523d82523d6000602084013e613462565b606091505b509150915081158061347657508051602014155b156134ad576040517f110b8e7300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808060200190518101906134c19190613f4d565b95505050505050612db7565b6000816004016040518581528385600483013760206000838360008b5af1925050508015610aea573d801561350e57600160005114601f3d11169150613516565b6000863b1191505b50949350505050565b60006020828403121561353157600080fd5b5035919050565b6000610140828403121561354b57600080fd5b50919050565b60006020828403121561356357600080fd5b813567ffffffffffffffff81111561357a57600080fd5b610aea84828501613538565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156135fc576135fc613586565b604052919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461362857600080fd5b919050565b600060e0828403121561363f57600080fd5b60405160e0810181811067ffffffffffffffff8211171561366257613662613586565b6040528235815290508061367860208401613604565b602082015261368960408401613604565b604082015261369a60608401613604565b60608201526136ab60808401613604565b608082015260a083013560a082015260c083013560c08201525092915050565b60008083601f8401126136dd57600080fd5b50813567ffffffffffffffff8111156136f557600080fd5b60208301915083602082850101111561224b57600080fd5b600080600080610120858703121561372457600080fd5b61372e868661362d565b935060e085013567ffffffffffffffff81111561374a57600080fd5b613756878288016136cb565b959890975094956101000135949350505050565b60008060006040848603121561377f57600080fd5b83359250602084013567ffffffffffffffff81111561379d57600080fd5b6137a9868287016136cb565b9497909650939450505050565b600080604083850312156137c957600080fd5b6137d283613604565b946020939093013593505050565b600080600080600061014086880312156137f957600080fd5b613803878761362d565b945060e086013567ffffffffffffffff81111561381f57600080fd5b61382b888289016136cb565b90955093505061010086013591506138466101208701613604565b90509295509295909350565b60008060008060008060008060c0898b03121561386e57600080fd5b883567ffffffffffffffff8082111561388657600080fd5b6138928c838d01613538565b995060208b01359150808211156138a857600080fd5b6138b48c838d016136cb565b909950975060408b01359150808211156138cd57600080fd5b506138da8b828c016136cb565b999c989b5096999698976060880135976080810135975060a0013595509350505050565b60006020828403121561391057600080fd5b61088082613604565b6000806000806000806000610160888a03121561393557600080fd5b61393f898961362d565b965060e088013567ffffffffffffffff8082111561395c57600080fd5b6139688b838c016136cb565b90985096506101008a013595508691506139856101208b01613604565b94506101408a013591508082111561399c57600080fd5b506139a98a828b016136cb565b989b979a50959850939692959293505050565b600060208083850312156139cf57600080fd5b823567ffffffffffffffff808211156139e757600080fd5b818501915085601f8301126139fb57600080fd5b813581811115613a0d57613a0d613586565b8060051b9150613a1e8483016135b5565b8181529183018401918481019088841115613a3857600080fd5b938501935b83851015613a5657843582529385019390850190613a3d565b98975050505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613a9a57835183529284019291840191600101613a7e565b50909695505050505050565b6000806000806101408587031215613abd57600080fd5b613ac7868661362d565b9660e08601359650610100860135956101200135945092505050565b600080600060408486031215613af857600080fd5b613b0184613604565b9250602084013567ffffffffffffffff81111561379d57600080fd5b60008060408385031215613b3057600080fd5b50508035926020909101359150565b60008060008060008060008060008060006101008c8e031215613b6157600080fd5b67ffffffffffffffff808d351115613b7857600080fd5b613b858e8e358f01613538565b9b508060208e01351115613b9857600080fd5b613ba88e60208f01358f016136cb565b909b50995060408d0135811015613bbe57600080fd5b613bce8e60408f01358f016136cb565b909950975060608d0135965060808d0135955060a08d01359450613bf460c08e01613604565b93508060e08e01351115613c0757600080fd5b50613c188d60e08e01358e016136cb565b81935080925050509295989b509295989b9093969950565b600080600080600080600080600060e08a8c031215613c4e57600080fd5b893567ffffffffffffffff80821115613c6657600080fd5b613c728d838e01613538565b9a5060208c0135915080821115613c8857600080fd5b613c948d838e016136cb565b909a50985060408c0135915080821115613cad57600080fd5b50613cba8c828d016136cb565b90975095505060608a0135935060808a0135925060a08a01359150613ce160c08b01613604565b90509295985092959850929598565b60008085851115613d0057600080fd5b83861115613d0d57600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561083457610834613d1a565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613dbc57613dbc613d1a565b5060010190565b8183823760009101908152919050565b60005b83811015613dee578181015183820152602001613dd6565b50506000910152565b82151581526040602082015260008251806040840152613e1e816060850160208701613dd3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b808202811582820484141761083457610834613d1a565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b888152600073ffffffffffffffffffffffffffffffffffffffff808a1660208401528089166040840152508660608301528560808301528460a083015260e060c0830152613f0360e083018486613e68565b9a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff86168152846020820152836040820152608060608201526000612db7608083018486613e68565b600060208284031215613f5f57600080fd5b5051919050565b600060208284031215613f7857600080fd5b8151801515811461088057600080fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613fbd57600080fd5b83018035915067ffffffffffffffff821115613fd857600080fd5b60200191503681900382131561224b57600080fd5b8181038181111561083457610834613d1a565b600082614036577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b8486823790930191825260208201526040810191909152606001919050565b6000825161409b818460208701613dd3565b919091019291505056fea264697066735822122057a4b2f141b321f193881112c3a0d0e5e22be10b804ee6bf7d45b729036daf8964736f6c63430008110033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/artifacts-v1/ResolverV1Mock.json b/artifacts-v1/ResolverV1Mock.json new file mode 100644 index 00000000..d8a10ca8 --- /dev/null +++ b/artifacts-v1/ResolverV1Mock.json @@ -0,0 +1,76 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "ResolverV1Mock", + "sourceName": "ResolverV1Mock.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "settlement", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "reason", + "type": "bytes" + } + ], + "name": "FailedExternalCall", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyOwner", + "type": "error" + }, + { + "inputs": [], + "name": "OnlySettlement", + "type": "error" + }, + { + "inputs": [], + "name": "SafeTransferFailed", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "resolver", + "type": "address" + }, + { + "internalType": "bytes", + "name": "tokensAndAmounts", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "resolveOrders", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60c060405234801561001057600080fd5b506040516109dd3803806109dd83398101604081905261002f91610044565b6001600160a01b03166080523360a052610074565b60006020828403121561005657600080fd5b81516001600160a01b038116811461006d57600080fd5b9392505050565b60805160a051610946610097600039600060b601526000605d01526109466000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80631944799f14610030575b600080fd5b61004361003e366004610485565b610045565b005b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100b4576040517f15b3197600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610139576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006101458284610521565b9050602082111561027f57600080610160846020818861055e565b81019061016d9190610731565b9150915060005b825181101561027b576000806101a0858481518110610195576101956107ea565b602002602001015190565b73ffffffffffffffffffffffffffffffffffffffff168484815181106101c8576101c86107ea565b60200260200101516040516101dd919061083d565b6000604051808303816000865af19150503d806000811461021a576040519150601f19603f3d011682016040523d82523d6000602084013e61021f565b606091505b5091509150816102685782816040517ffac829a000000000000000000000000000000000000000000000000000000000815260040161025f929190610859565b60405180910390fd5b505080610274906108b1565b9050610174565b5050505b846040850460005b8181101561037657600081818682602081106102a5576102a56107ea565b1a905060ff8114610368575b8585838181106102c3576102c36107ea565b9050604002016020013583019250600382901b60ff60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c87179650809150868160208110610318576103186107ea565b1a905060008290036102b157610368338461034b89898981811061033e5761033e6107ea565b9050604002016000013590565b73ffffffffffffffffffffffffffffffffffffffff169190610381565b505050806001019050610287565b505050505050505050565b6103ad837fa9059cbb0000000000000000000000000000000000000000000000000000000084846103e8565b6103e3576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60006040518481528360048201528260248201526020600060448360008a5af19150508015610434573d801561042a57600160005114601f3d11169150610432565b6000863b1191505b505b949350505050565b60008083601f84011261044e57600080fd5b50813567ffffffffffffffff81111561046657600080fd5b60208301915083602082850101111561047e57600080fd5b9250929050565b60008060008060006060868803121561049d57600080fd5b853573ffffffffffffffffffffffffffffffffffffffff811681146104c157600080fd5b9450602086013567ffffffffffffffff808211156104de57600080fd5b6104ea89838a0161043c565b9096509450604088013591508082111561050357600080fd5b506105108882890161043c565b969995985093965092949392505050565b80356020831015610558577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b165b92915050565b6000808585111561056e57600080fd5b8386111561057b57600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156105fe576105fe610588565b604052919050565b600067ffffffffffffffff82111561062057610620610588565b5060051b60200190565b6000601f838184011261063c57600080fd5b8235602061065161064c83610606565b6105b7565b82815260059290921b8501810191818101908784111561067057600080fd5b8287015b8481101561072557803567ffffffffffffffff808211156106955760008081fd5b818a0191508a603f8301126106aa5760008081fd5b858201356040828211156106c0576106c0610588565b6106ef887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08c850116016105b7565b92508183528c818386010111156107065760008081fd5b8181850189850137506000908201870152845250918301918301610674565b50979650505050505050565b6000806040838503121561074457600080fd5b823567ffffffffffffffff8082111561075c57600080fd5b818501915085601f83011261077057600080fd5b8135602061078061064c83610606565b82815260059290921b8401810191818101908984111561079f57600080fd5b948201945b838610156107bd578535825294820194908201906107a4565b965050860135925050808211156107d357600080fd5b506107e08582860161062a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b8381101561083457818101518382015260200161081c565b50506000910152565b6000825161084f818460208701610819565b9190910192915050565b828152604060208201526000825180604084015261087e816060850160208701610819565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610909577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea26469706673582212200cf9ff8d83a00e9966440e7c8238ff27a6d8500339bc248abbc678bd061a67c564736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80631944799f14610030575b600080fd5b61004361003e366004610485565b610045565b005b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146100b4576040517f15b3197600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614610139576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006101458284610521565b9050602082111561027f57600080610160846020818861055e565b81019061016d9190610731565b9150915060005b825181101561027b576000806101a0858481518110610195576101956107ea565b602002602001015190565b73ffffffffffffffffffffffffffffffffffffffff168484815181106101c8576101c86107ea565b60200260200101516040516101dd919061083d565b6000604051808303816000865af19150503d806000811461021a576040519150601f19603f3d011682016040523d82523d6000602084013e61021f565b606091505b5091509150816102685782816040517ffac829a000000000000000000000000000000000000000000000000000000000815260040161025f929190610859565b60405180910390fd5b505080610274906108b1565b9050610174565b5050505b846040850460005b8181101561037657600081818682602081106102a5576102a56107ea565b1a905060ff8114610368575b8585838181106102c3576102c36107ea565b9050604002016020013583019250600382901b60ff60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c87179650809150868160208110610318576103186107ea565b1a905060008290036102b157610368338461034b89898981811061033e5761033e6107ea565b9050604002016000013590565b73ffffffffffffffffffffffffffffffffffffffff169190610381565b505050806001019050610287565b505050505050505050565b6103ad837fa9059cbb0000000000000000000000000000000000000000000000000000000084846103e8565b6103e3576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b60006040518481528360048201528260248201526020600060448360008a5af19150508015610434573d801561042a57600160005114601f3d11169150610432565b6000863b1191505b505b949350505050565b60008083601f84011261044e57600080fd5b50813567ffffffffffffffff81111561046657600080fd5b60208301915083602082850101111561047e57600080fd5b9250929050565b60008060008060006060868803121561049d57600080fd5b853573ffffffffffffffffffffffffffffffffffffffff811681146104c157600080fd5b9450602086013567ffffffffffffffff808211156104de57600080fd5b6104ea89838a0161043c565b9096509450604088013591508082111561050357600080fd5b506105108882890161043c565b969995985093965092949392505050565b80356020831015610558577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff602084900360031b1b165b92915050565b6000808585111561056e57600080fd5b8386111561057b57600080fd5b5050820193919092039150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156105fe576105fe610588565b604052919050565b600067ffffffffffffffff82111561062057610620610588565b5060051b60200190565b6000601f838184011261063c57600080fd5b8235602061065161064c83610606565b6105b7565b82815260059290921b8501810191818101908784111561067057600080fd5b8287015b8481101561072557803567ffffffffffffffff808211156106955760008081fd5b818a0191508a603f8301126106aa5760008081fd5b858201356040828211156106c0576106c0610588565b6106ef887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08c850116016105b7565b92508183528c818386010111156107065760008081fd5b8181850189850137506000908201870152845250918301918301610674565b50979650505050505050565b6000806040838503121561074457600080fd5b823567ffffffffffffffff8082111561075c57600080fd5b818501915085601f83011261077057600080fd5b8135602061078061064c83610606565b82815260059290921b8401810191818101908984111561079f57600080fd5b948201945b838610156107bd578535825294820194908201906107a4565b965050860135925050808211156107d357600080fd5b506107e08582860161062a565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60005b8381101561083457818101518382015260200161081c565b50506000910152565b6000825161084f818460208701610819565b9190910192915050565b828152604060208201526000825180604084015261087e816060850160208701610819565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610909577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea26469706673582212200cf9ff8d83a00e9966440e7c8238ff27a6d8500339bc248abbc678bd061a67c564736f6c63430008110033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/artifacts-v1/SettlementV1.json b/artifacts-v1/SettlementV1.json new file mode 100644 index 00000000..41fc600e --- /dev/null +++ b/artifacts-v1/SettlementV1.json @@ -0,0 +1,199 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "SettlementV1", + "sourceName": "SettlementV1.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "contract IOrderMixin", + "name": "limitOrderProtocol", + "type": "address" + }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AccessDenied", + "type": "error" + }, + { + "inputs": [], + "name": "FailedExternalCall", + "type": "error" + }, + { + "inputs": [], + "name": "ForceApproveFailed", + "type": "error" + }, + { + "inputs": [], + "name": "IncorrectCalldataParams", + "type": "error" + }, + { + "inputs": [], + "name": "NotEnoughCredit", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyFeeBankAccess", + "type": "error" + }, + { + "inputs": [], + "name": "ResolverIsNotWhitelisted", + "type": "error" + }, + { + "inputs": [], + "name": "SafeTransferFailed", + "type": "error" + }, + { + "inputs": [], + "name": "WrongInteractionTarget", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "availableCredit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "decreaseAvailableCredit", + "outputs": [ + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "feeBank", + "outputs": [ + { + "internalType": "contract IFeeBank", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "taker", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "takingAmount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "interactiveData", + "type": "bytes" + } + ], + "name": "fillOrderInteraction", + "outputs": [ + { + "internalType": "uint256", + "name": "result", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "increaseAvailableCredit", + "outputs": [ + { + "internalType": "uint256", + "name": "allowance", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "settleOrders", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "bytecode": "0x60c060405234801561001057600080fd5b50604051620022c8380380620022c8833981016040819052610031916100c1565b803081336040516100419061009b565b6001600160a01b03938416815291831660208301529091166040820152606001604051809103906000f08015801561007d573d6000803e3d6000fd5b506001600160a01b039081166080529290921660a052506100fb9050565b611048806200128083390190565b6001600160a01b03811681146100be57600080fd5b50565b600080604083850312156100d457600080fd5b82516100df816100a9565b60208401519092506100f0816100a9565b809150509250929050565b60805160a0516111436200013d6000396000818161035b015281816106a4015261077f01526000818161010001528181610197015261026901526111436000f3fe608060405234801561001057600080fd5b50600436106100725760003560e01c806385eda2de1161005057806385eda2de146100e8578063af15d786146100fb578063ccee33d71461014757600080fd5b80630965d04b146100775780633ee5ef1f1461008c5780635886216f146100b2575b600080fd5b61008a610085366004610d52565b61015a565b005b61009f61009a366004610dbd565b61017d565b6040519081526020015b60405180910390f35b61009f6100c0366004610de7565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61009f6100f6366004610dbd565b61024f565b6101227f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a9565b61009f610155366004610e09565b6102f1565b60408051600080825260208201909252610179918491849133916106db565b5050565b60003373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146101ee576040517fa454419900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205461021f8282610ecf565b73ffffffffffffffffffffffffffffffffffffffff90931660009081526020819052604090208390555090919050565b60003373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146102c0576040517fa454419900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205461021f8282610ee8565b60008573ffffffffffffffffffffffffffffffffffffffff81163014610343576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146103b2576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8284017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081810135918290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff40810192918101919060018801908881037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f01907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80810135906298968090610489907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0013582610ecf565b610493908d610efb565b61049d9190610f12565b97506000633b9aca006104bd63ffffffff60808a013560a01c168b610efb565b6104c79190610f12565b905060006104d6866040610ecf565b67ffffffffffffffff8111156104ee576104ee610e71565b6040519080825280601f01601f191660200182016040528015610518576020820181803683370190505b509050602081018688823786018381528a83016020909101527f01000000000000000000000000000000000000000000000000000000000000008c8c60008161056357610563610f4d565b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361064b576105a3602089013589356108a3565b60006105af8587610f7c565b60601c90503660006105c4876014818b610fc4565b915091508273ffffffffffffffffffffffffffffffffffffffff16631944799f6105ef8d6020013590565b8685856040518563ffffffff1660e01b81526004016106119493929190610fee565b600060405180830381600087803b15801561062b57600080fd5b505af115801561063f573d6000803e3d6000fd5b5050505050505061065d565b61065d858560208b01358b35856106db565b81156106885761068873ffffffffffffffffffffffffffffffffffffffff841660808a013584610936565b6106c973ffffffffffffffffffffffffffffffffffffffff84167f00000000000000000000000000000000000000000000000000000000000000008c61099d565b50505050505050505095945050505050565b843585016106e98185610a66565b61071f576040517f4b57606900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061072a82610b37565b905061074766038d7ea4c6800063ffffffff843560901c16610efb565b6107519085610ecf565b9350600061075e83610b70565b90506000845160a06107709190610ecf565b61077b906020610ecf565b90507f00000000000000000000000000000000000000000000000000000000000000006107b1565b8281848460045afa50505050565b60408a013560208101818c0135818d013560601c308114156014831017156107fd577f5b34bf890000000000000000000000000000000000000000000000000000000060005260046000fd5b506040517fe5d7bde60000000000000000000000000000000000000000000000000000000081528c8e600483013785820160048583010152818382010193508a60048501528b60248501526040890135604485015286606485015287608485015289516108718160208d0160a488016107a3565b84810160a40152600081878f016004018183895af1610893573d6000823e3d81fd5b5050505050505050505050505050565b80156101795773ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610909576040517fa7fd379200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff92909216600090815260208190526040902091039055565b610962837fa9059cbb000000000000000000000000000000000000000000000000000000008484610cb5565b610998576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6109c9837f095ea7b3000000000000000000000000000000000000000000000000000000008484610cb5565b610998576109fa837f095ea7b300000000000000000000000000000000000000000000000000000000846000610cb5565b1580610a2f5750610a2d837f095ea7b3000000000000000000000000000000000000000000000000000000008484610cb5565b155b15610998576040517f19be9a9000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003681610a786101208601866110a8565b91509150600181830103803560001a6004820391506080811615610a9d576020820391505b813560e01c4211945060031c600f16841915610b2d578060180282035b80831115610b2b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe88301927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec013560601c833560e01c888203610b24574210159650610b2b9050565b5050610aba565b505b5050505092915050565b60003681610b496101208501856110a8565b91509150600181830103803560001a60801615610b6857602081033593505b505050919050565b600062ffffff823560b081901c82169160e082901c918491610b969160c81c1683610ecf565b9050814211610ba85750909392505050565b804210610bba57506000949350505050565b366000610bcb6101208801886110a8565b915091506001818301036000813560001a6078811660031c6007821692506080821615610bf9576020840393505b6004816018020184039350505086868260050284035b80851115610c95577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb8501803560f01c9990990198947ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd013560e81c428a1115610c8b57828a03428481038302908c03860201049b5050610c95565b9250889150610c0f565b5089610ca75780870342880383020499505b505050505050505050919050565b60006040518481528360048201528260248201526020600060448360008a5af19150508015610d01573d8015610cf757600160005114601f3d11169150610cff565b6000863b1191505b505b949350505050565b60008083601f840112610d1b57600080fd5b50813567ffffffffffffffff811115610d3357600080fd5b602083019150836020828501011115610d4b57600080fd5b9250929050565b60008060208385031215610d6557600080fd5b823567ffffffffffffffff811115610d7c57600080fd5b610d8885828601610d09565b90969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610db857600080fd5b919050565b60008060408385031215610dd057600080fd5b610dd983610d94565b946020939093013593505050565b600060208284031215610df957600080fd5b610e0282610d94565b9392505050565b600080600080600060808688031215610e2157600080fd5b610e2a86610d94565b94506020860135935060408601359250606086013567ffffffffffffffff811115610e5457600080fd5b610e6088828901610d09565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610ee257610ee2610ea0565b92915050565b81810381811115610ee257610ee2610ea0565b8082028115828204841417610ee257610ee2610ea0565b600082610f48577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008135818116916014851015610fbc5780818660140360031b1b83161692505b505092915050565b60008085851115610fd457600080fd5b83861115610fe157600080fd5b5050820193919092039150565b73ffffffffffffffffffffffffffffffffffffffff8516815260006020606081840152855180606085015260005b818110156110385787810183015185820160800152820161101c565b506000608082860101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0915081601f820116840190506080848203016040850152846080820152848660a0830137600060a0868301015260a082601f8701168201019250505095945050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110dd57600080fd5b83018035915067ffffffffffffffff8211156110f857600080fd5b602001915036819003821315610d4b57600080fdfea26469706673582212203d85afe0def838d7432972596f81cedd8117e5f3d6e095f4947a8eaf06bf1a6864736f6c6343000811003360c06040523480156200001157600080fd5b5060405162001048380380620010488339810160408190526200003491620001ad565b6200003f3362000066565b6001600160a01b0380841660a05282166080526200005d81620000b6565b50505062000201565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b620000c062000139565b6001600160a01b0381166200012b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084015b60405180910390fd5b620001368162000066565b50565b6000546001600160a01b03163314620001955760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000122565b565b6001600160a01b03811681146200013657600080fd5b600080600060608486031215620001c357600080fd5b8351620001d08162000197565b6020850151909350620001e38162000197565b6040850151909250620001f68162000197565b809150509250925092565b60805160a051610df7620002516000396000818161028b015281816103a0015281816105a9015261072b015260008181610207015281816104640152818161064801526106a00152610df76000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063715018a611610081578063b6b55f251161005b578063b6b55f2514610185578063bfe9173414610198578063f2fde38b146101ab57600080fd5b8063715018a6146101405780638da5cb5b1461014a57806397a2cb641461017257600080fd5b80632f4f21e2116100b25780632f4f21e21461010757806332d323a51461011a5780635886216f1461012d57600080fd5b8063205c2878146100ce5780632e1a7d4d146100f4575b600080fd5b6100e16100dc366004610b1a565b6101be565b6040519081526020015b60405180910390f35b6100e1610102366004610b44565b6101d3565b6100e1610115366004610b1a565b6101df565b6100e1610128366004610ba6565b6101eb565b6100e161013b366004610c00565b610243565b6101486102f8565b005b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100eb565b6100e1610180366004610c4a565b61030c565b6100e1610193366004610b44565b610491565b6100e16101a6366004610d2d565b61049d565b6101486101b9366004610c00565b6104b5565b60006101ca8383610571565b90505b92915050565b60006101cd3383610571565b60006101ca8383610684565b600061022e73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016848461079a565b6102388585610684565b90505b949350505050565b6040517f5886216f00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690635886216f90602401602060405180830381865afa1580156102d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101cd9190610d79565b6103006107b6565b61030a6000610837565b565b60006103166107b6565b815160005b8181101561044957600084828151811061033757610337610d92565b60209081029190910181015173ffffffffffffffffffffffffffffffffffffffff8082166000818152600190945260408085205490517f5886216f00000000000000000000000000000000000000000000000000000000815260048101929092529294509192917f000000000000000000000000000000000000000000000000000000000000000090911690635886216f90602401602060405180830381865afa1580156103e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040d9190610d79565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600160208190526040909120849055929091039490940193500161031b565b5061048b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633846108ac565b50919050565b60006101cd3383610684565b60006104ab338585856101eb565b90505b9392505050565b6104bd6107b6565b73ffffffffffffffffffffffffffffffffffffffff8116610565576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61056e81610837565b50565b6040517f85eda2de000000000000000000000000000000000000000000000000000000008152336004820152602481018290526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16906385eda2de906044016020604051808303816000875af1158015610607573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061062b9190610d79565b3360009081526001602052604090208054849003905590506101cd7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1684846108ac565b60006106c873ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001633308561090e565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602052604090819020805486019055517f3ee5ef1f0000000000000000000000000000000000000000000000000000000081526004810191909152602481018490527f000000000000000000000000000000000000000000000000000000000000000090911690633ee5ef1f906044016020604051808303816000875af1158015610776573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101ca9190610d79565b6107a58383836109ab565b6107b1576107b1610a51565b505050565b60005473ffffffffffffffffffffffffffffffffffffffff16331461030a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161055c565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6108d8837fa9059cbb000000000000000000000000000000000000000000000000000000008484610a5d565b6107b1576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006323b872dd60e01b905060006040518281528560048201528460248201528360448201526020600060648360008b5af1915050801561096c573d801561096257600160005114601f3d1116915061096a565b6000873b1191505b505b806109a3576040517ff405907100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050565b600060e08290036109e9576109e2847fd505accf000000000000000000000000000000000000000000000000000000008585610ab0565b90506104ae565b610100829003610a1f576109e2847f8fcbaf0c000000000000000000000000000000000000000000000000000000008585610ab0565b6040517f6827585700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040513d6000823e3d81fd5b60006040518481528360048201528260248201526020600060448360008a5af1915050801561023b573d8015610a9f57600160005114601f3d11169150610aa7565b6000863b1191505b50949350505050565b6000816004016040518581528385600483013760206000838360008b5af192505050801561023b573d8015610a9f57600160005114601f3d11169150610aa7565b803573ffffffffffffffffffffffffffffffffffffffff81168114610b1557600080fd5b919050565b60008060408385031215610b2d57600080fd5b610b3683610af1565b946020939093013593505050565b600060208284031215610b5657600080fd5b5035919050565b60008083601f840112610b6f57600080fd5b50813567ffffffffffffffff811115610b8757600080fd5b602083019150836020828501011115610b9f57600080fd5b9250929050565b60008060008060608587031215610bbc57600080fd5b610bc585610af1565b935060208501359250604085013567ffffffffffffffff811115610be857600080fd5b610bf487828801610b5d565b95989497509550505050565b600060208284031215610c1257600080fd5b6101ca82610af1565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020808385031215610c5d57600080fd5b823567ffffffffffffffff80821115610c7557600080fd5b818501915085601f830112610c8957600080fd5b813581811115610c9b57610c9b610c1b565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610cde57610cde610c1b565b604052918252848201925083810185019188831115610cfc57600080fd5b938501935b82851015610d2157610d1285610af1565b84529385019392850192610d01565b98975050505050505050565b600080600060408486031215610d4257600080fd5b83359250602084013567ffffffffffffffff811115610d6057600080fd5b610d6c86828701610b5d565b9497909650939450505050565b600060208284031215610d8b57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fdfea264697066735822122079e400ea25a12686fb120107d9d3eef6eec02df300cbebb2c1ed5a9d34fca96664736f6c63430008110033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c806385eda2de1161005057806385eda2de146100e8578063af15d786146100fb578063ccee33d71461014757600080fd5b80630965d04b146100775780633ee5ef1f1461008c5780635886216f146100b2575b600080fd5b61008a610085366004610d52565b61015a565b005b61009f61009a366004610dbd565b61017d565b6040519081526020015b60405180910390f35b61009f6100c0366004610de7565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61009f6100f6366004610dbd565b61024f565b6101227f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100a9565b61009f610155366004610e09565b6102f1565b60408051600080825260208201909252610179918491849133916106db565b5050565b60003373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146101ee576040517fa454419900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205461021f8282610ecf565b73ffffffffffffffffffffffffffffffffffffffff90931660009081526020819052604090208390555090919050565b60003373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146102c0576040517fa454419900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205461021f8282610ee8565b60008573ffffffffffffffffffffffffffffffffffffffff81163014610343576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016146103b2576040517f4ca8886700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8284017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081810135918290037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff40810192918101919060018801908881037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3f01907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80810135906298968090610489907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa0013582610ecf565b610493908d610efb565b61049d9190610f12565b97506000633b9aca006104bd63ffffffff60808a013560a01c168b610efb565b6104c79190610f12565b905060006104d6866040610ecf565b67ffffffffffffffff8111156104ee576104ee610e71565b6040519080825280601f01601f191660200182016040528015610518576020820181803683370190505b509050602081018688823786018381528a83016020909101527f01000000000000000000000000000000000000000000000000000000000000008c8c60008161056357610563610f4d565b9050013560f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160361064b576105a3602089013589356108a3565b60006105af8587610f7c565b60601c90503660006105c4876014818b610fc4565b915091508273ffffffffffffffffffffffffffffffffffffffff16631944799f6105ef8d6020013590565b8685856040518563ffffffff1660e01b81526004016106119493929190610fee565b600060405180830381600087803b15801561062b57600080fd5b505af115801561063f573d6000803e3d6000fd5b5050505050505061065d565b61065d858560208b01358b35856106db565b81156106885761068873ffffffffffffffffffffffffffffffffffffffff841660808a013584610936565b6106c973ffffffffffffffffffffffffffffffffffffffff84167f00000000000000000000000000000000000000000000000000000000000000008c61099d565b50505050505050505095945050505050565b843585016106e98185610a66565b61071f576040517f4b57606900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061072a82610b37565b905061074766038d7ea4c6800063ffffffff843560901c16610efb565b6107519085610ecf565b9350600061075e83610b70565b90506000845160a06107709190610ecf565b61077b906020610ecf565b90507f00000000000000000000000000000000000000000000000000000000000000006107b1565b8281848460045afa50505050565b60408a013560208101818c0135818d013560601c308114156014831017156107fd577f5b34bf890000000000000000000000000000000000000000000000000000000060005260046000fd5b506040517fe5d7bde60000000000000000000000000000000000000000000000000000000081528c8e600483013785820160048583010152818382010193508a60048501528b60248501526040890135604485015286606485015287608485015289516108718160208d0160a488016107a3565b84810160a40152600081878f016004018183895af1610893573d6000823e3d81fd5b5050505050505050505050505050565b80156101795773ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610909576040517fa7fd379200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff92909216600090815260208190526040902091039055565b610962837fa9059cbb000000000000000000000000000000000000000000000000000000008484610cb5565b610998576040517ffb7f507900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b6109c9837f095ea7b3000000000000000000000000000000000000000000000000000000008484610cb5565b610998576109fa837f095ea7b300000000000000000000000000000000000000000000000000000000846000610cb5565b1580610a2f5750610a2d837f095ea7b3000000000000000000000000000000000000000000000000000000008484610cb5565b155b15610998576040517f19be9a9000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003681610a786101208601866110a8565b91509150600181830103803560001a6004820391506080811615610a9d576020820391505b813560e01c4211945060031c600f16841915610b2d578060180282035b80831115610b2b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe88301927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec013560601c833560e01c888203610b24574210159650610b2b9050565b5050610aba565b505b5050505092915050565b60003681610b496101208501856110a8565b91509150600181830103803560001a60801615610b6857602081033593505b505050919050565b600062ffffff823560b081901c82169160e082901c918491610b969160c81c1683610ecf565b9050814211610ba85750909392505050565b804210610bba57506000949350505050565b366000610bcb6101208801886110a8565b915091506001818301036000813560001a6078811660031c6007821692506080821615610bf9576020840393505b6004816018020184039350505086868260050284035b80851115610c95577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffb8501803560f01c9990990198947ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd013560e81c428a1115610c8b57828a03428481038302908c03860201049b5050610c95565b9250889150610c0f565b5089610ca75780870342880383020499505b505050505050505050919050565b60006040518481528360048201528260248201526020600060448360008a5af19150508015610d01573d8015610cf757600160005114601f3d11169150610cff565b6000863b1191505b505b949350505050565b60008083601f840112610d1b57600080fd5b50813567ffffffffffffffff811115610d3357600080fd5b602083019150836020828501011115610d4b57600080fd5b9250929050565b60008060208385031215610d6557600080fd5b823567ffffffffffffffff811115610d7c57600080fd5b610d8885828601610d09565b90969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610db857600080fd5b919050565b60008060408385031215610dd057600080fd5b610dd983610d94565b946020939093013593505050565b600060208284031215610df957600080fd5b610e0282610d94565b9392505050565b600080600080600060808688031215610e2157600080fd5b610e2a86610d94565b94506020860135935060408601359250606086013567ffffffffffffffff811115610e5457600080fd5b610e6088828901610d09565b969995985093965092949392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610ee257610ee2610ea0565b92915050565b81810381811115610ee257610ee2610ea0565b8082028115828204841417610ee257610ee2610ea0565b600082610f48577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008135818116916014851015610fbc5780818660140360031b1b83161692505b505092915050565b60008085851115610fd457600080fd5b83861115610fe157600080fd5b5050820193919092039150565b73ffffffffffffffffffffffffffffffffffffffff8516815260006020606081840152855180606085015260005b818110156110385787810183015185820160800152820161101c565b506000608082860101527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0915081601f820116840190506080848203016040850152846080820152848660a0830137600060a0868301015260a082601f8701168201019250505095945050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126110dd57600080fd5b83018035915067ffffffffffffffff8211156110f857600080fd5b602001915036819003821315610d4b57600080fdfea26469706673582212203d85afe0def838d7432972596f81cedd8117e5f3d6e095f4947a8eaf06bf1a6864736f6c63430008110033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/contracts/mocks/SettlementExtensionMock.sol b/contracts/mocks/SettlementExtensionMock.sol new file mode 100644 index 00000000..f4550c9b --- /dev/null +++ b/contracts/mocks/SettlementExtensionMock.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.19; + +import "../SettlementExtension.sol"; + +contract SettlementExtensionMock is SettlementExtension { + constructor(IOrderMixin limitOrderProtocol, IERC20 token) + SettlementExtension(limitOrderProtocol, token) + {} + + function decreaseAvailableCreditMock(address account, uint256 amount) external { + _chargeFee(account, amount); + } +} diff --git a/package.json b/package.json index 85839a5a..561957c5 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "@openzeppelin/contracts": "4.8.2" }, "devDependencies": { + "@1inch/limit-order-settlement-v1": "git+https://github.com/1inch/limit-order-settlement.git#feature/settlement-v1", "@matterlabs/hardhat-zksync-deploy": "0.6.3", "@matterlabs/hardhat-zksync-solc": "0.3.16", "@matterlabs/hardhat-zksync-verify": "0.1.4", diff --git a/test/FeeBank.js b/test/FeeBank.js index a8dfa686..35a8a12c 100644 --- a/test/FeeBank.js +++ b/test/FeeBank.js @@ -11,8 +11,8 @@ describe('FeeBank', function () { const [owner, alice] = await ethers.getSigners(); const inch = await deployContract('ERC20PermitMock', ['1INCH', '1INCH', owner.address, ether('1000')]); - const { swap } = await deploySwapTokens(); - const matcher = await deployContract('SettlementMock', [swap.address, inch.address]); + const { lopv4 } = await deploySwapTokens(); + const matcher = await deployContract('SettlementExtensionMock', [lopv4.address, inch.address]); const FeeBank = await ethers.getContractFactory('FeeBank'); const feeBank = FeeBank.attach(await matcher.feeBank()); diff --git a/test/MeasureGas.js b/test/MeasureGas.js index b9b7b8be..b6869491 100644 --- a/test/MeasureGas.js +++ b/test/MeasureGas.js @@ -1,10 +1,12 @@ +const fs = require('fs'); const hre = require('hardhat'); +const path = require('path'); const { ethers } = hre; const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { time, expect, ether, trim0x } = require('@1inch/solidity-utils'); const { deploySwapTokens, getChainId, deployContract } = require('./helpers/fixtures'); -const { buildOrder, signOrder, buildTakerTraits, fillWithMakingAmount, buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); -const { buildFusions } = require('./helpers/fusionUtils'); +const { buildOrder, signOrder, buildTakerTraits, buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); +const settlementV1Utils = require('@1inch/limit-order-settlement-v1/test/helpers/orderUtils'); const RESOLVERS_NUMBER = 10; @@ -17,18 +19,25 @@ describe('MeasureGas', function () { const [owner, alice] = await ethers.getSigners(); const chainId = await getChainId(); const abiCoder = ethers.utils.defaultAbiCoder; - const { dai, weth, inch, swap } = await deploySwapTokens(); + const { dai, weth, inch, lopv3, lopv4 } = await deploySwapTokens(); await dai.transfer(alice.address, ether('100')); await inch.mint(owner.address, ether('100')); await weth.deposit({ value: ether('1') }); await weth.connect(alice).deposit({ value: ether('1') }); - const settlementExtension = await deployContract('SettlementExtension', [swap.address, inch.address]); - const settlement = await deployContract('Settlement', [swap.address, inch.address]); + const settlementExtension = await deployContract('SettlementExtension', [lopv4.address, inch.address]); + const SettlementV1 = JSON.parse(fs.readFileSync(path.join(__dirname, '../artifacts-v1/SettlementV1.json'), 'utf8')); + // const settlement = await deployContract(SettlementV1.abi, [lopv3.address, inch.address]); + const ContractFactory = await ethers.getContractFactory(SettlementV1.abi, SettlementV1.bytecode); + const settlement = await ContractFactory.deploy(lopv3.address, inch.address); + const resolvers = []; + const ResolverV1Mock = JSON.parse(fs.readFileSync(path.join(__dirname, '../artifacts-v1/ResolverV1Mock.json'), 'utf8')); for (let i = 0; i < RESOLVERS_NUMBER; i++) { - resolvers[i] = await deployContract('ResolverMock', [settlement.address, swap.address]); + // resolvers[i] = await deployContract(ResolverV1Mock.abi, [settlement.address, lopv3.address]); + const ResolverMockFactory = await ethers.getContractFactory(ResolverV1Mock.abi, ResolverV1Mock.bytecode); + resolvers[i] = await ResolverMockFactory.deploy(settlement.address); } const FeeBank = await ethers.getContractFactory('FeeBank'); const feeBank = FeeBank.attach(await settlement.feeBank()); @@ -36,7 +45,7 @@ describe('MeasureGas', function () { await feeBank.depositFor(resolvers[0].address, ether('100')); return { - contracts: { dai, weth, swap, settlement, settlementExtension, feeBank, resolvers }, + contracts: { dai, weth, lopv3, lopv4, settlement, settlementExtension, feeBank, resolvers }, accounts: { owner, alice }, others: { chainId, abiCoder }, }; @@ -44,163 +53,218 @@ describe('MeasureGas', function () { async function initContractsAndApproves() { const data = await initContracts(); - const { contracts: { dai, weth, swap }, accounts: { alice } } = data; - await dai.approve(swap.address, ether('100')); - await dai.connect(alice).approve(swap.address, ether('100')); - await weth.approve(swap.address, ether('1')); - await weth.connect(alice).approve(swap.address, ether('1')); + const { contracts: { dai, weth, lopv3, lopv4 }, accounts: { alice } } = data; + for (const swap of [lopv3, lopv4]) { + await dai.approve(swap.address, ether('100')); + await dai.connect(alice).approve(swap.address, ether('100')); + await weth.approve(swap.address, ether('1')); + await weth.connect(alice).approve(swap.address, ether('1')); + } return data; } - it('1 fill for 1 order', async function () { - const { contracts: { dai, weth, swap, settlement, resolvers }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContractsAndApproves); - - const { fusions: [fusionDetails], hashes: [fusionDetailsHash], resolvers: fusionResolvers } = await buildFusions([ - { resolvers: [resolvers[0].address] }, - ]); - const order = buildOrder({ - maker: alice.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), - }); - order.salt = fusionDetailsHash; - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, alice)); - - const fillOrderToData = swap.interface.encodeFunctionData('fillOrderArgs', [ - order, - r, - vs, - ether('100'), - fillWithMakingAmount('0'), - resolvers[0].address, - settlement.address + '01' + trim0x(fusionDetails), - ]) + trim0x(fusionResolvers); - - await weth.transfer(resolvers[0].address, ether('0.1')); - - const tx = await resolvers[0].settleOrders(fillOrderToData); - console.log(`1 fill for 1 order gasUsed: ${(await tx.wait()).gasUsed}`); - await expect(tx).to.changeTokenBalances(dai, [resolvers[0], alice], [ether('100'), ether('-100')]); - await expect(tx).to.changeTokenBalances(weth, [owner, alice], [ether('-0.1'), ether('0.1')]); - }); + describe('SettlementV1', function () { + it('1 fill for 1 order', async function () { + const { contracts: { dai, weth, lopv3, settlement, resolvers }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContractsAndApproves); + + const makerAsset = dai.address; + const takerAsset = weth.address; + const makingAmount = ether('100'); + const takingAmount = ether('0.1'); + const order = await settlementV1Utils.buildOrder( + { + salt: settlementV1Utils.buildSalt({ + orderStartTime: await time.latest(), + initialStartRate: 0, + duration: time.duration.hours(1), + }), + makerAsset, + takerAsset, + makingAmount, + takingAmount, + from: alice.address, + }, + { + whitelistedAddrs: [owner.address, ...(resolvers.map(r => r.address))], + whitelistedCutOffs: [0, ...(resolvers.map(r => 0))], + publicCutOff: time.duration.minutes(30), + }, + ); + const signature = await settlementV1Utils.signOrder(order, chainId, lopv3.address, alice); - it.only('extension 1 fill for 1 order', async function () { - const { contracts: { dai, weth, swap, settlementExtension }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContractsAndApproves); - - const auctionStartTime = await time.latest(); - const auctionDetails = ethers.utils.solidityPack( - ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], - ); - - const order = buildOrder({ - maker: alice.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), - makerTraits: buildMakerTraits(), - }, { - makingAmountData: settlementExtension.address + trim0x(auctionDetails), - takingAmountData: settlementExtension.address + trim0x(auctionDetails), - postInteraction: settlementExtension.address + trim0x(ethers.utils.solidityPack( - ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + owner.address.substring(22), 0], - )), + const interaction = + settlement.address + + '01' + + trim0x(resolvers[0].address) + + '0000000000000000000000000000000000000000000000000000000000000000' + + ''; + await weth.transfer(resolvers[0].address, takingAmount); + + const tx = await settlement.settleOrders( + '0x' + lopv3.interface.encodeFunctionData('fillOrderTo', [ + order, + signature, + interaction, + makingAmount, + 0, + takingAmount, + resolvers[0].address, + ]).substring(10), + ); + console.log(`1 fill for 1 order gasUsed: ${(await tx.wait()).gasUsed}`); + await expect(tx).to.changeTokenBalances(dai, [resolvers[0], alice], [ether('100'), ether('-100')]); + await expect(tx).to.changeTokenBalances(weth, [resolvers[0], alice], [ether('-0.1'), ether('0.1')]); }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, swap.address, alice)); + it('1 fill for 5 orders in a batch', async function () { + const { contracts: { dai, weth, lopv3, settlement, resolvers }, accounts: { alice, owner }, others: { chainId } } = await loadFixture(initContractsAndApproves); - await weth.approve(swap.address, ether('0.1')); + const resolverAddresses = resolvers.map(r => r.address); + const whitelistedCutOffsTmp = resolvers.map(r => 0); - const takerTraits = buildTakerTraits({ - makingAmount: true, - minReturn: ether('0.1'), - extension: order.extension, - }); + // Build orders and compact signatures + const orders = []; + const signatures = []; + for (let i = 0; i < 4; i++) { + orders[i] = await settlementV1Utils.buildOrder( + { + salt: settlementV1Utils.buildSalt({ + orderStartTime: await time.latest(), + initialStartRate: 0, + duration: time.duration.hours(1), + }), + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether((i + 1).toString()), + takingAmount: ether(((i + 1) / 100).toString()), + from: alice.address, + }, + { + whitelistedAddrs: [owner.address, ...resolverAddresses], + whitelistedCutOffs: [0, ...whitelistedCutOffsTmp], + publicCutOff: time.duration.minutes(30), + }, + ); + signatures[i] = await settlementV1Utils.signOrder(orders[i], chainId, lopv3.address, alice); + } + orders[4] = await settlementV1Utils.buildOrder( + { + salt: settlementV1Utils.buildSalt({ + orderStartTime: await time.latest(), + initialStartRate: 0, + duration: time.duration.hours(1), + }), + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: ether('0.11'), // takingAmount/100 * 1.1 + takingAmount: ether('1'), // (max_i - 1) * max_i / 2 + from: owner.address, + }, + { + whitelistedAddrs: [owner.address, ...resolverAddresses], + whitelistedCutOffs: [0, ...whitelistedCutOffsTmp], + publicCutOff: time.duration.minutes(30), + }, + ); + signatures[4] = await settlementV1Utils.signOrder(orders[4], chainId, lopv3.address, owner); + + // Encode data for fillingg orders + const fillOrdersToData = []; - const tx = await swap.fillOrderArgs( - order, - r, - vs, - ether('100'), - takerTraits.traits, - takerTraits.args, - ); - console.log(`1 fill for 1 order gasUsed: ${(await tx.wait()).gasUsed}`); - await expect(tx).to.changeTokenBalances(dai, [owner, alice], [ether('100'), ether('-100')]); - await expect(tx).to.changeTokenBalances(weth, [owner, alice], [ether('-0.1'), ether('0.1')]); + fillOrdersToData[5] = settlement.address + '01' + trim0x(resolvers[0].address) + '0000000000000000000000000000000000000000000000000000000000000000'; + fillOrdersToData[4] = + settlement.address + + '00' + + lopv3.interface + .encodeFunctionData('fillOrderTo', [ + orders[4], + signatures[4], + fillOrdersToData[5], + ether('0.11'), + 0, + ether('10'), + resolvers[0].address, + ]) + .substring(10); + for (let i = 3; i >= 1; i--) { + fillOrdersToData[i] = + settlement.address + + '00' + + lopv3.interface + .encodeFunctionData('fillOrderTo', [ + orders[i], + signatures[i], + fillOrdersToData[i + 1], + ether((i + 1).toString()), + 0, + ether(((i + 1) / 100).toString()), + resolvers[0].address, + ]) + .substring(10); + } + + const tx = await settlement.settleOrders( + '0x' + lopv3.interface.encodeFunctionData('fillOrderTo', [ + orders[0], + signatures[0], + fillOrdersToData[1], + ether('1'), + 0, + ether('0.01'), + resolvers[0].address, // settlement.address, + ]).substring(10), + ); + console.log(`1 fill for 5 orders in a batch gasUsed: ${(await tx.wait()).gasUsed}`); + await expect(tx).to.changeTokenBalances(weth, [owner, alice], [ether('-0.11'), ether('0.1')]); + await expect(tx).to.changeTokenBalances(dai, [owner, alice, resolvers[0]], [ether('1'), ether('-10'), ether('9')]); + }); }); - it('1 fill for 5 orders in a batch', async function () { - const { contracts: { dai, weth, swap, settlement, resolvers }, accounts: { alice, owner }, others: { chainId } } = await loadFixture(initContractsAndApproves); - - const resolverAddresses = resolvers.map(r => r.address); - const { fusions: fusionDetails, hashes: fusionHashes, resolvers: fusionResolvers } = await buildFusions([ - { resolvers: resolverAddresses }, - { resolvers: resolverAddresses }, - { resolvers: resolverAddresses }, - { resolvers: resolverAddresses }, - { resolvers: resolverAddresses }, - ]); - - // Build orders and compact signatures - const orders = []; - const signatures = []; - for (let i = 0; i < 4; i++) { - orders[i] = buildOrder({ + describe('SettlementExtension', function () { + it('extension 1 fill for 1 order', async function () { + const { contracts: { dai, weth, lopv4, settlementExtension }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContractsAndApproves); + + const auctionStartTime = await time.latest(); + const auctionDetails = ethers.utils.solidityPack( + ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], + ); + + const order = buildOrder({ maker: alice.address, makerAsset: dai.address, takerAsset: weth.address, - makingAmount: ether((i + 1).toString()), - takingAmount: ether(((i + 1) / 100).toString()), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), + }, { + makingAmountData: settlementExtension.address + trim0x(auctionDetails), + takingAmountData: settlementExtension.address + trim0x(auctionDetails), + postInteraction: settlementExtension.address + trim0x(ethers.utils.solidityPack( + ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + owner.address.substring(22), 0], + )), }); - orders[i].salt = fusionHashes[i]; - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(orders[i], chainId, swap.address, alice)); - signatures[i] = { r, vs }; - } - orders[4] = buildOrder({ - maker: owner.address, - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.1'), // takingAmount/100 - takingAmount: ether('10'), // (max_i - 1) * max_i / 2 - makerTraits: settlement.address, - }); - orders[4].salt = fusionHashes[4]; - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(orders[4], chainId, swap.address, owner)); - - signatures[4] = { r, vs }; - - // Encode data for fillingg orders - const fillOrdersToData = []; - fillOrdersToData[4] = swap.interface.encodeFunctionData('fillOrderTo', [ - orders[4], - signatures[4].r, - signatures[4].vs, - ether('0.1'), - fillWithMakingAmount('0'), - resolvers[0].address, - settlement.address + '01' + trim0x(fusionDetails[4]), - ]); - for (let i = 3; i >= 0; i--) { - fillOrdersToData[i] = swap.interface.encodeFunctionData('fillOrderTo', [ - orders[i], - signatures[i].r, - signatures[i].vs, - ether((i + 1).toString()), - fillWithMakingAmount('0'), - resolvers[0].address, - settlement.address + '00' + trim0x(fusionDetails[i]) + trim0x(fillOrdersToData[i + 1]), - ]); - } - fillOrdersToData[0] += trim0x(fusionResolvers); - const tx = await resolvers[0].settleOrders(fillOrdersToData[0]); - console.log(`1 fill for 5 orders in a batch gasUsed: ${(await tx.wait()).gasUsed}`); - await expect(tx).to.changeTokenBalances(weth, [owner, alice], [ether('-0.1'), ether('0.1')]); - await expect(tx).to.changeTokenBalances(dai, [owner, alice], [ether('10'), ether('-10')]); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, lopv4.address, alice)); + + await weth.approve(lopv4.address, ether('0.1')); + + const takerTraits = buildTakerTraits({ + makingAmount: true, + minReturn: ether('0.1'), + extension: order.extension, + }); + + const tx = await lopv4.fillOrderArgs( + order, + r, + vs, + ether('100'), + takerTraits.traits, + takerTraits.args, + ); + console.log(`1 fill for 1 order gasUsed: ${(await tx.wait()).gasUsed}`); + await expect(tx).to.changeTokenBalances(dai, [owner, alice], [ether('100'), ether('-100')]); + await expect(tx).to.changeTokenBalances(weth, [owner, alice], [ether('-0.1'), ether('0.1')]); + }); }); }); diff --git a/test/Settlement.js b/test/Settlement.js index 63db6a5d..ffd794c9 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -9,7 +9,7 @@ const ORDER_FEE = 100n; const BACK_ORDER_FEE = 125n; const BASE_POINTS = ether('0.001'); // 1e15 -describe('Settlement', function () { +describe.skip('Settlement', function () { async function initContracts() { const abiCoder = ethers.utils.defaultAbiCoder; const chainId = await getChainId(); diff --git a/test/WhitelistChecker.js b/test/WhitelistChecker.js index 079a5c9b..3c64f128 100644 --- a/test/WhitelistChecker.js +++ b/test/WhitelistChecker.js @@ -5,30 +5,30 @@ const { expect, ether, trim0x, deployContract } = require('@1inch/solidity-utils const { deploySwapTokens, getChainId } = require('./helpers/fixtures'); const { buildFusions } = require('./helpers/fusionUtils'); -describe('WhitelistChecker', function () { +describe.skip('WhitelistChecker // TODO: Update this tests', function () { async function initContracts() { const [owner, alice] = await ethers.getSigners(); const chainId = await getChainId(); - const { dai, weth, swap } = await deploySwapTokens(); + const { dai, weth, lopv4 } = await deploySwapTokens(); await dai.mint(owner.address, ether('100')); await dai.mint(alice.address, ether('100')); await weth.deposit({ value: ether('1') }); await weth.connect(alice).deposit({ value: ether('1') }); - await dai.approve(swap.address, ether('100')); - await dai.connect(alice).approve(swap.address, ether('100')); - await weth.approve(swap.address, ether('1')); - await weth.connect(alice).approve(swap.address, ether('1')); + await dai.approve(lopv4.address, ether('100')); + await dai.connect(alice).approve(lopv4.address, ether('100')); + await weth.approve(lopv4.address, ether('1')); + await weth.connect(alice).approve(lopv4.address, ether('1')); const whitelistRegistrySimple = await deployContract('WhitelistRegistrySimple', []); - const settlement = await deployContract('Settlement', [swap.address, weth.address]); + const settlement = await deployContract('SettlementExtension', [lopv4.address, weth.address]); const ResolverMock = await ethers.getContractFactory('ResolverMock'); - const resolver = await ResolverMock.deploy(settlement.address, swap.address); + const resolver = await ResolverMock.deploy(settlement.address, lopv4.address); return { - contracts: { dai, weth, swap, whitelistRegistrySimple, settlement, resolver }, + contracts: { dai, weth, lopv4, whitelistRegistrySimple, settlement, resolver }, accounts: { owner, alice }, others: { chainId }, }; @@ -36,7 +36,7 @@ describe('WhitelistChecker', function () { describe('should not work with non-whitelisted address', function () { it('whitelist check in settleOrders method', async function () { - const { contracts: { dai, weth, swap, settlement }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContracts); + const { contracts: { dai, weth, lopv4, settlement }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContracts); const { fusions: [fusionDetails], hashes: [fusionHash], resolvers } = await buildFusions([{}]); @@ -49,8 +49,8 @@ describe('WhitelistChecker', function () { }); order.salt = fusionHash; - const { r, vs } = compactSignature(await signOrder(order, chainId, swap.address, alice)); - const fillOrderToData = swap.interface.encodeFunctionData('fillOrderTo', [ + const { r, vs } = compactSignature(await signOrder(order, chainId, lopv4.address, alice)); + const fillOrderToData = lopv4.interface.encodeFunctionData('fillOrderTo', [ order, r, vs, @@ -65,7 +65,7 @@ describe('WhitelistChecker', function () { }); it('onlyThis modifier in takerInteraction method', async function () { - const { contracts: { dai, weth, swap, settlement }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContracts); + const { contracts: { dai, weth, lopv4, settlement }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContracts); const order = buildOrder({ makerAsset: dai.address, @@ -75,13 +75,13 @@ describe('WhitelistChecker', function () { maker: alice.address, }); - const { r, vs } = compactSignature(await signOrder(order, chainId, swap.address, alice)); - await expect(swap.fillOrderTo(order, r, vs, ether('10'), fillWithMakingAmount('0'), owner.address, settlement.address + '01')) + const { r, vs } = compactSignature(await signOrder(order, chainId, lopv4.address, alice)); + await expect(lopv4.fillOrderTo(order, r, vs, ether('10'), fillWithMakingAmount('0'), owner.address, settlement.address + '01')) .to.be.revertedWithCustomError(settlement, 'AccessDenied'); }); it('onlyLimitOrderProtocol modifier', async function () { - const { contracts: { dai, weth, swap, settlement }, accounts: { owner, alice } } = await loadFixture(initContracts); + const { contracts: { dai, weth, lopv4, settlement }, accounts: { owner, alice } } = await loadFixture(initContracts); const order = buildOrder({ makerAsset: dai.address, @@ -90,7 +90,7 @@ describe('WhitelistChecker', function () { takingAmount: ether('0.1'), maker: alice.address, }); - const orderHash = await swap.hashOrder(order); + const orderHash = await lopv4.hashOrder(order); await expect(settlement.takerInteraction(order, orderHash, owner.address, '1', '1', '0', '0x')) .to.be.revertedWithCustomError(settlement, 'AccessDenied'); @@ -106,7 +106,7 @@ describe('WhitelistChecker', function () { } it('whitelist check in settleOrders method', async function () { - const { contracts: { dai, weth, swap, settlement, resolver }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContractsAndSetStatus); + const { contracts: { dai, weth, lopv4, settlement, resolver }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContractsAndSetStatus); const { fusions: [fusionDetails0, fusionDetails1], hashes: [fusionHash0, fusionHash1], resolvers } = await buildFusions([ { resolvers: [resolver.address] }, @@ -131,8 +131,8 @@ describe('WhitelistChecker', function () { }); order1.salt = fusionHash1; - const { r: r1, vs: vs1 } = compactSignature(await signOrder(order1, chainId, swap.address, alice)); - const fillOrderToData1 = swap.interface.encodeFunctionData('fillOrderTo', [ + const { r: r1, vs: vs1 } = compactSignature(await signOrder(order1, chainId, lopv4.address, alice)); + const fillOrderToData1 = lopv4.interface.encodeFunctionData('fillOrderTo', [ order1, r1, vs1, @@ -142,8 +142,8 @@ describe('WhitelistChecker', function () { settlement.address + '01' + trim0x(fusionDetails1), ]); - const { r: r0, vs: vs0 } = compactSignature(await signOrder(order0, chainId, swap.address, owner)); - const fillOrderToData0 = swap.interface.encodeFunctionData('fillOrderTo', [ + const { r: r0, vs: vs0 } = compactSignature(await signOrder(order0, chainId, lopv4.address, owner)); + const fillOrderToData0 = lopv4.interface.encodeFunctionData('fillOrderTo', [ order0, r0, vs0, diff --git a/test/helpers/fixtures.js b/test/helpers/fixtures.js index 0854a215..45360efc 100644 --- a/test/helpers/fixtures.js +++ b/test/helpers/fixtures.js @@ -1,3 +1,5 @@ +const fs = require('fs'); +const path = require('path'); const { ethers } = require('hardhat'); const { ether, deployContract } = require('@1inch/solidity-utils'); @@ -10,8 +12,13 @@ async function deploySwapTokens() { const dai = await deployContract('ERC20PermitMock', ['DAI', 'DAI', account.address, ether('1000')]); const weth = await deployContract('WrappedTokenMock', ['WETH', 'WETH']); const inch = await deployContract('TokenMock', ['1INCH', '1INCH']); - const swap = await deployContract('LimitOrderProtocol', [weth.address]); - return { dai, weth, inch, swap }; + const lopv4 = await deployContract('LimitOrderProtocol', [weth.address]); + + const LimitOrderProtocolV3 = JSON.parse(fs.readFileSync(path.join(__dirname, '../../artifacts-v1/LimitOrderProtocolV3.json'), 'utf8')); + // const lopv3 = await deployContract(LimitOrderProtocolV3.abi, [weth.address]); + const ContractFactory = await ethers.getContractFactory(LimitOrderProtocolV3.abi, LimitOrderProtocolV3.bytecode); + const lopv3 = await ContractFactory.deploy(weth.address); + return { dai, weth, inch, lopv3, lopv4 }; } module.exports = { diff --git a/yarn.lock b/yarn.lock index 9360bf27..5c60cdb0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -38,6 +38,15 @@ "@1inch/solidity-utils" "2.2.5" "@openzeppelin/contracts" "4.8.0" +"@1inch/limit-order-protocol-contract@3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@1inch/limit-order-protocol-contract/-/limit-order-protocol-contract-3.0.0.tgz#cca48bc9a2253c4fd964e1032aa1791e354989ab" + integrity sha512-6O1T1erbfJfs+yNiLtrD/2rSe38Mptf+h9CwM07Hm2ZM/kba0mGjSLUAanQsZkkGs0MZGrKrop9WyLF+IRMz/A== + dependencies: + "@1inch/solidity-utils" "2.2.2" + "@chainlink/contracts" "0.5.1" + "@openzeppelin/contracts" "4.7.3" + "@1inch/limit-order-protocol-contract@4.0.0-prerelease-14": version "4.0.0-prerelease-14" resolved "https://registry.yarnpkg.com/@1inch/limit-order-protocol-contract/-/limit-order-protocol-contract-4.0.0-prerelease-14.tgz#6f2eb42b13fbfc4fda6cf95271ae2703f58127f2" @@ -47,6 +56,29 @@ "@chainlink/contracts" "0.6.1" "@openzeppelin/contracts" "4.9.0" +"@1inch/limit-order-settlement-v1@git+https://github.com/1inch/limit-order-settlement.git#feature/settlement-v1": + version "0.0.1" + resolved "git+https://github.com/1inch/limit-order-settlement.git#7801eca16384e52705eafe3e7bcffc96223a50ed" + dependencies: + "@1inch/delegating" "0.0.21" + "@1inch/erc20-pods" "0.0.16" + "@1inch/limit-order-protocol-contract" "3.0.0" + "@1inch/solidity-utils" "2.2.5" + "@openzeppelin/contracts" "4.8.0" + +"@1inch/solidity-utils@2.2.2": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@1inch/solidity-utils/-/solidity-utils-2.2.2.tgz#3c7165b0131426a11abd35a556fa244a5ac0c59b" + integrity sha512-nO65pP6fgbc0RUbKaI7PrqZdM20KjK6FONrh3iOf5o5y+iH/kf7njcUwXSU9hEB/UmnTUD0lr2LeGOwiCVDCkg== + dependencies: + "@metamask/eth-sig-util" "4.0.1" + "@nomicfoundation/hardhat-network-helpers" "1.0.6" + "@nomiclabs/hardhat-ethers" "2.1.1" + "@openzeppelin/contracts" "4.7.3" + ethereumjs-util "7.1.5" + ethers "5.7.1" + hardhat "2.11.2" + "@1inch/solidity-utils@2.2.21": version "2.2.21" resolved "https://registry.yarnpkg.com/@1inch/solidity-utils/-/solidity-utils-2.2.21.tgz#921917234893b0fe6b7190395a4bb9495652a54c" @@ -95,25 +127,31 @@ "@1inch/solidity-utils" "2.2.21" "@openzeppelin/contracts" "4.8.2" +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + "@babel/code-frame@^7.0.0": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" - integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== dependencies: - "@babel/highlight" "^7.18.6" + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" -"@babel/helper-validator-identifier@^7.18.6": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== +"@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== +"@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" js-tokens "^4.0.0" "@balena/dockerignore@^1.0.2": @@ -121,6 +159,15 @@ resolved "https://registry.yarnpkg.com/@balena/dockerignore/-/dockerignore-1.0.2.tgz#9ffe4726915251e8eb69f44ef3547e0da2c03e0d" integrity sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q== +"@chainlink/contracts@0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@chainlink/contracts/-/contracts-0.5.1.tgz#68e7447ba8c1eccfbb760bacc93aced2eef60945" + integrity sha512-3PDBJ38Sd6Ml9h7FNK/tZQti+kTCdXUq1qzE6E59CnlzycsV9ElPvf2hTvs9Mi9C6pEx2Mmw9yhZMfBktYUInQ== + dependencies: + "@eth-optimism/contracts" "^0.5.21" + "@openzeppelin/contracts" "^4.3.3" + "@openzeppelin/contracts-v0.7" "npm:@openzeppelin/contracts@v3.4.2" + "@chainlink/contracts@0.6.1": version "0.6.1" resolved "https://registry.yarnpkg.com/@chainlink/contracts/-/contracts-0.6.1.tgz#8842b57e755793cbdbcbc45277fb5d179c993e19" @@ -150,15 +197,6 @@ dependencies: "@chainsafe/as-sha256" "^0.3.1" -"@chainsafe/ssz@0.9.4", "@chainsafe/ssz@^0.9.2": - version "0.9.4" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" - integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.4.2" - case "^1.6.3" - "@chainsafe/ssz@^0.10.0": version "0.10.2" resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" @@ -167,6 +205,15 @@ "@chainsafe/as-sha256" "^0.3.1" "@chainsafe/persistent-merkle-tree" "^0.5.0" +"@chainsafe/ssz@^0.9.2": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" + integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== + dependencies: + "@chainsafe/as-sha256" "^0.3.1" + "@chainsafe/persistent-merkle-tree" "^0.4.2" + case "^1.6.3" + "@eslint-community/eslint-utils@^4.2.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -175,18 +222,18 @@ eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.4.0": - version "4.5.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.0.tgz#f6f729b02feee2c749f57e334b7a1b5f40a81724" - integrity sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ== + version "4.9.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.9.1.tgz#449dfa81a57a1d755b09aa58d826c1262e4283b4" + integrity sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA== "@eslint/eslintrc@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.2.tgz#01575e38707add677cf73ca1589abba8da899a02" - integrity sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ== + version "2.1.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" + integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.5.1" + espree "^9.6.0" globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -235,16 +282,16 @@ resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== -"@ethereumjs/util@^8.0.0": - version "8.0.5" - resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.0.5.tgz#b9088fc687cc13f0c1243d6133d145dfcf3fe446" - integrity sha512-259rXKK3b3D8HRVdRmlOEi6QFvwxdt304hhrEAmpZhsj7ufXEOTIc9JRZPMnXatKjECokdLNBcDOFBeBSzAIaw== +"@ethereumjs/util@^8.0.0", "@ethereumjs/util@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/util/-/util-8.1.0.tgz#299df97fb6b034e0577ce9f94c7d9d1004409ed4" + integrity sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA== dependencies: - "@chainsafe/ssz" "0.9.4" "@ethereumjs/rlp" "^4.0.1" - ethereum-cryptography "^1.1.2" + ethereum-cryptography "^2.0.0" + micro-ftch "^0.3.1" -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.7.0": +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== @@ -612,10 +659,15 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" +"@fastify/busboy@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.0.0.tgz#f22824caff3ae506b18207bad4126dbc6ccdb6b8" + integrity sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ== + "@humanwhocodes/config-array@^0.11.8": - version "0.11.8" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" - integrity sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g== + version "0.11.11" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.11.tgz#88a04c570dbbc7dd943e4712429c3df09bc32844" + integrity sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA== dependencies: "@humanwhocodes/object-schema" "^1.2.1" debug "^4.1.1" @@ -689,11 +741,28 @@ tweetnacl "^1.0.3" tweetnacl-util "^0.15.1" +"@noble/curves@1.1.0", "@noble/curves@~1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" + integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== + dependencies: + "@noble/hashes" "1.3.1" + "@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== +"@noble/hashes@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + +"@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + "@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" @@ -1184,9 +1253,9 @@ undici "^5.14.0" "@openzeppelin/contracts-upgradeable@^4.7.3": - version "4.8.2" - resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.2.tgz#edef522bdbc46d478481391553bababdd2199e27" - integrity sha512-zIggnBwemUmmt9IS73qxi+tumALxCY4QEs3zLCII78k0Gfse2hAOdAkuAeLUzvWUpneMUfFE5sGHzEUSTvn4Ag== + version "4.9.3" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.9.3.tgz#ff17a80fb945f5102571f8efecb5ce5915cc4811" + integrity sha512-jjaHAVRMrE4UuZNfDwjlLGDxTHWIOwTJS2ldnc278a0gevfXfPr8hxKEVBGFBE96kl2G3VHDZhUimw/+G3TG2A== "@openzeppelin/contracts-v0.7@npm:@openzeppelin/contracts@v3.4.2": version "3.4.2" @@ -1213,15 +1282,20 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.0.tgz#683f33b6598970051bc5f0806fd8660da9e018dd" integrity sha512-DUP74AFGKlic2sQb/CmgrN2aUPMFGxRrmCTUxLHsiU2RzwWqVuMPZBxiAyvlff6Pea77uylAX6B5x9W6evEbhA== +"@openzeppelin/contracts@^4.3.3": + version "4.9.3" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364" + integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg== + "@openzeppelin/contracts@~4.3.3": version "4.3.3" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.3.3.tgz#ff6ee919fc2a1abaf72b22814bfb72ed129ec137" integrity sha512-tDBopO1c98Yk7Cv/PZlHqrvtVjlgK5R4J6jxLwoO7qxK4xqOiZG+zSkIvGFpPZ0ikc3QOED3plgdqjgNTnBc7g== "@scure/base@~1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" - integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== + version "1.1.3" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.3.tgz#8584115565228290a6c6c4961973e0903bb3df2f" + integrity sha512-/+SgoRjLq7Xlf0CWuLHq2LUZeL/w65kfzAPG5NH9pcmBhs+nunQTn4gvdwgMTIXnt9b2C/1SeL2XiysZEyIC9Q== "@scure/bip32@1.1.5": version "1.1.5" @@ -1232,6 +1306,15 @@ "@noble/secp256k1" "~1.7.0" "@scure/base" "~1.1.0" +"@scure/bip32@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10" + integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A== + dependencies: + "@noble/curves" "~1.1.0" + "@noble/hashes" "~1.3.1" + "@scure/base" "~1.1.0" + "@scure/bip39@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" @@ -1240,6 +1323,14 @@ "@noble/hashes" "~1.2.0" "@scure/base" "~1.1.0" +"@scure/bip39@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" + integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== + dependencies: + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + "@sentry/core@5.30.0": version "5.30.0" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" @@ -1316,16 +1407,16 @@ antlr4ts "^0.5.0-alpha.4" "@solidity-parser/parser@^0.16.0": - version "0.16.0" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.0.tgz#1fb418c816ca1fc3a1e94b08bcfe623ec4e1add4" - integrity sha512-ESipEcHyRHg4Np4SqBCfcXwyxxna1DgFVz69bgpLV8vzl/NP1DtcKsJ4dJZXWQhY/Z4J2LeKBiOkOVZn9ct33Q== + version "0.16.1" + resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.16.1.tgz#f7c8a686974e1536da0105466c4db6727311253c" + integrity sha512-PdhRFNhbTtu3x8Axm0uYpqOy/lODYQK+MlYSgqIsq2L8SFYEHJPHNUiOTAJbDGzNjjr1/n9AcIayxafR/fWmYw== dependencies: antlr4ts "^0.5.0-alpha.4" "@types/async-eventemitter@^0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz#f8e6280e87e8c60b2b938624b0a3530fb3e24712" - integrity sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg== + version "0.2.2" + resolved "https://registry.yarnpkg.com/@types/async-eventemitter/-/async-eventemitter-0.2.2.tgz#8212e16aecb5056901f04fae7b174d2f65bba60e" + integrity sha512-cUFkZN+0TXQ2HYX/vbVUa/0+3/kXtuVrojjzq4Yo8X68UDvwngMf7uOZWT7BcA5P6MhCNd/zOCuczgPAQxsNIQ== "@types/bn.js@^4.11.3": version "4.11.6" @@ -1335,23 +1426,23 @@ "@types/node" "*" "@types/bn.js@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" - integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.2.tgz#162f5238c46f4bcbac07a98561724eca1fcf0c5e" + integrity sha512-dkpZu0szUtn9UXTmw+e0AJFd4D2XAxDnsCLdc05SfqpqzPEBft8eQr8uaFitfo/dUUOZERaLec2hHMG87A4Dxg== dependencies: "@types/node" "*" "@types/chai-as-promised@^7.1.3": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz#6e016811f6c7a64f2eed823191c3a6955094e255" - integrity sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ== + version "7.1.6" + resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.6.tgz#3b08cbe1e7206567a480dc6538bade374b19e4e1" + integrity sha512-cQLhk8fFarRVZAXUQV1xEnZgMoPxqKojBvRkqPCKPQCzEhpbbSKl1Uu75kDng7k5Ln6LQLUmNBjLlFthCgm1NA== dependencies: "@types/chai" "*" "@types/chai@*": - version "4.3.4" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.4.tgz#e913e8175db8307d78b4e8fa690408ba6b65dee4" - integrity sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw== + version "4.3.6" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.6.tgz#7b489e8baf393d5dd1266fb203ddd4ea941259e6" + integrity sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw== "@types/concat-stream@^1.6.0": version "1.6.1" @@ -1391,9 +1482,9 @@ integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== "@types/node@*": - version "18.15.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.11.tgz#b3b790f09cb1696cffcec605de025b088fa4225f" - integrity sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q== + version "20.8.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.3.tgz#c4ae2bb1cfab2999ed441a95c122bbbe1567a66d" + integrity sha512-jxiZQFpb+NlH5kjW49vXxvxTjeeqlbsnTAdBTKpzEdPs9itay7MscYXz3Fo9VYFEsfQ6LJFitHad3faerLAjCw== "@types/node@^10.0.3": version "10.17.60" @@ -1413,9 +1504,9 @@ "@types/node" "*" "@types/qs@^6.2.31", "@types/qs@^6.9.7": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + version "6.9.8" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.8.tgz#f2a7de3c107b89b441e071d5472e6b726b4adf45" + integrity sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg== "@types/readable-stream@^2.3.13": version "2.3.15" @@ -1426,9 +1517,9 @@ safe-buffer "~5.1.1" "@types/secp256k1@^4.0.1": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" - integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.4.tgz#33c760de627fce1f449c2d4270da07e4da54c830" + integrity sha512-oN0PFsYxDZnX/qSJ5S5OwaEDTYfekhvaM5vqui2bu1AA39pKofmgL104Q29KiOXizXS2yLjSzc5YdTyMKdcy4A== dependencies: "@types/node" "*" @@ -1483,10 +1574,10 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.8.0: - version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== +acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== address@^1.0.1: version "1.2.2" @@ -1518,7 +1609,7 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.6: +ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.6: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1595,9 +1686,9 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: color-convert "^2.0.1" antlr4@^4.11.0: - version "4.12.0" - resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.12.0.tgz#e2323fbb057c77068a174914b0533398aeaba56a" - integrity sha512-23iB5IzXJZRZeK9TigzUyrNc9pSmNqAerJRBcNq1ETrmttMWRgaYZzC561IgEO3ygKsDJTYDTozABXa4b/fTQQ== + version "4.13.1" + resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1.tgz#1e0a1830a08faeb86217cb2e6c34716004e4253d" + integrity sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA== antlr4ts@^0.5.0-alpha.4: version "0.5.0-alpha.4" @@ -1633,14 +1724,14 @@ array-buffer-byte-length@^1.0.0: is-array-buffer "^3.0.1" array-includes@^3.1.6: - version "3.1.6" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" - integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== + version "3.1.7" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" + integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - get-intrinsic "^1.1.3" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" is-string "^1.0.7" array-union@^2.1.0: @@ -1653,54 +1744,73 @@ array-uniq@1.0.3: resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== +array.prototype.findlast@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.findlast/-/array.prototype.findlast-1.2.3.tgz#4e4b375de5adf4897fed155e2d2771564865cc3b" + integrity sha512-kcBubumjciBg4JKp5KTKtI7ec7tRefPk88yjkWJwaVKYd9QfTaxcsOxoMNKd7iBr447zCfDV0z1kOF47umv42g== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + array.prototype.flat@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" - integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" array.prototype.flatmap@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" - integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" -array.prototype.reduce@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" - integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== +array.prototype.reduce@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz#63149931808c5fc1e1354814923d92d45f7d96d5" + integrity sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" es-array-method-boxes-properly "^1.0.0" is-string "^1.0.7" +arraybuffer.prototype.slice@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" + integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== -asn1@^0.2.4, asn1@~0.2.3: +asn1@^0.2.6: version "0.2.6" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== dependencies: safer-buffer "~2.1.0" -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== - assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -1745,16 +1855,6 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== - -aws4@^1.8.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" - integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== - axios@^0.21.1: version "0.21.4" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" @@ -1762,10 +1862,10 @@ axios@^0.21.1: dependencies: follow-redirects "^1.14.0" -axios@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.4.tgz#f5760cefd9cfb51fd2481acf88c05f67c4523024" - integrity sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ== +axios@^1.3.4, axios@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.5.1.tgz#11fbaa11fc35f431193a9564109c88c1f27b585f" + integrity sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A== dependencies: follow-redirects "^1.15.0" form-data "^4.0.0" @@ -1788,7 +1888,7 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -bcrypt-pbkdf@^1.0.0, bcrypt-pbkdf@^1.0.2: +bcrypt-pbkdf@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== @@ -1801,16 +1901,9 @@ bech32@1.1.4: integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== bigint-crypto-utils@^3.0.23: - version "3.1.8" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz#e2e0f40cf45488f9d7f0e32ff84152aa73819d5d" - integrity sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw== - dependencies: - bigint-mod-arith "^3.1.0" - -bigint-mod-arith@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz#658e416bc593a463d97b59766226d0a3021a76b1" - integrity sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ== + version "3.3.0" + resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" + integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== binary-extensions@^2.0.0: version "2.2.0" @@ -1969,14 +2062,14 @@ buffer@^6.0.3: ieee754 "^1.2.1" bufio@^1.0.7: - version "1.2.0" - resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.2.0.tgz#b9ad1c06b0d9010363c387c39d2810a7086d143f" - integrity sha512-UlFk8z/PwdhYQTXSQQagwGAdtRI83gib2n4uy4rQnenxUM2yQi8lBDzF230BNk+3wAoZDxYRoBwVVUPgHa9MCA== + version "1.2.1" + resolved "https://registry.yarnpkg.com/bufio/-/bufio-1.2.1.tgz#8d4ab3ddfcd5faa90f996f922f9397d41cbaf2de" + integrity sha512-9oR3zNdupcg/Ge2sSHQF3GX+kmvL/fTPvD0nd5AGLq8SjUYnTz+SlFjK/GXidndbZtIj+pVKXiWeR9w6e9wKCA== -buildcheck@0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.3.tgz#70451897a95d80f7807e68fc412eb2e7e35ff4d5" - integrity sha512-pziaA+p/wdVImfcbsZLNF32EiWyujlQLwolMqUQE8xpKNOH7KmZQaY8sXN7DGOEzPAElo9QTaeNRfGnf3iOJbA== +buildcheck@~0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/buildcheck/-/buildcheck-0.0.6.tgz#89aa6e417cfd1e2196e3f8fe915eb709d2fe4238" + integrity sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A== builtins@^5.0.1: version "5.0.1" @@ -1985,13 +2078,6 @@ builtins@^5.0.1: dependencies: semver "^7.0.0" -busboy@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -2049,7 +2135,7 @@ chai-as-promised@^7.1.1: dependencies: check-error "^1.0.2" -chai@4.3.7, chai@^4.3.4: +chai@4.3.7: version "4.3.7" resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== @@ -2062,6 +2148,19 @@ chai@4.3.7, chai@^4.3.4: pathval "^1.1.1" type-detect "^4.0.5" +chai@^4.3.4: + version "4.3.10" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.10.tgz#d784cec635e3b7e2ffb66446a63b4e33bd390384" + integrity sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.3" + deep-eql "^4.1.3" + get-func-name "^2.0.2" + loupe "^2.3.6" + pathval "^1.1.1" + type-detect "^4.0.8" + chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -2070,7 +2169,7 @@ chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^2.0.0, chalk@^2.4.2: +chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2084,10 +2183,12 @@ chalk@^2.0.0, chalk@^2.4.2: resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== +check-error@^1.0.2, check-error@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.3.tgz#a6502e4312a7ee969f646e83bb3ddd56281bd694" + integrity sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg== + dependencies: + get-func-name "^2.0.2" chokidar@3.3.0: version "3.3.0" @@ -2138,14 +2239,14 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: safe-buffer "^5.0.1" classic-level@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.2.0.tgz#2d52bdec8e7a27f534e67fdeb890abef3e643c27" - integrity sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg== + version "1.3.0" + resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" + integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg== dependencies: abstract-level "^1.0.2" catering "^2.1.0" module-error "^1.0.1" - napi-macros "~2.0.0" + napi-macros "^2.2.2" node-gyp-build "^4.3.0" clean-stack@^2.0.0: @@ -2210,7 +2311,7 @@ colors@1.4.0, colors@^1.1.2: resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -2228,9 +2329,9 @@ commander@3.0.2: integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== commander@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.0.tgz#71797971162cd3cf65f0b9d24eb28f8d303acdf1" - integrity sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA== + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== commander@^8.1.0: version "8.3.0" @@ -2257,33 +2358,28 @@ cookie@^0.4.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== - core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== cosmiconfig@^8.0.0: - version "8.1.3" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.1.3.tgz#0e614a118fcc2d9e5afc2f87d53cd09931015689" - integrity sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw== + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== dependencies: - import-fresh "^3.2.1" + import-fresh "^3.3.0" js-yaml "^4.1.0" - parse-json "^5.0.0" + parse-json "^5.2.0" path-type "^4.0.0" -cpu-features@~0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.4.tgz#0023475bb4f4c525869c162e4108099e35bf19d8" - integrity sha512-fKiZ/zp1mUwQbnzb9IghXtHtDoTMtNeb8oYGx6kX2SYfhnG0HNdBEBIzB9b5KlXu5DQPhfy3mInbBxFcgwAr3A== +cpu-features@~0.0.8: + version "0.0.9" + resolved "https://registry.yarnpkg.com/cpu-features/-/cpu-features-0.0.9.tgz#5226b92f0f1c63122b0a3eb84cb8335a4de499fc" + integrity sha512-AKjgn2rP2yJyfbepsmLfiYcmtNn/2eUvocUyM/09yB0YDiz39HteK/5/T4Onf0pmdYDMgkBoGvRLvEguzyL7wQ== dependencies: - buildcheck "0.0.3" - nan "^2.15.0" + buildcheck "~0.0.6" + nan "^2.17.0" crc-32@^1.2.0: version "1.2.2" @@ -2327,13 +2423,6 @@ cross-spawn@^7.0.2: resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== - dependencies: - assert-plus "^1.0.0" - death@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" @@ -2370,7 +2459,7 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== -deep-eql@^4.0.1, deep-eql@^4.1.2: +deep-eql@^4.0.1, deep-eql@^4.1.2, deep-eql@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== @@ -2382,11 +2471,21 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== -define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" - integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== +define-data-property@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.0.tgz#0db13540704e1d8d479a0656cf781267531b9451" + integrity sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g== dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + +define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" has-property-descriptors "^1.0.0" object-keys "^1.1.1" @@ -2489,14 +2588,6 @@ dotenv@16.0.3: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" @@ -2533,11 +2624,12 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: once "^1.4.0" enquirer@^2.3.0, enquirer@^2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== dependencies: ansi-colors "^4.1.1" + strip-ansi "^6.0.1" env-paths@^2.2.0: version "2.2.1" @@ -2551,18 +2643,19 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.21.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" - integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== +es-abstract@^1.22.1: + version "1.22.2" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.2.tgz#90f7282d91d0ad577f505e423e52d4c1d93c1b8a" + integrity sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA== dependencies: array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.2" available-typed-arrays "^1.0.5" call-bind "^1.0.2" es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.2.0" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.1" get-symbol-description "^1.0.0" globalthis "^1.0.3" gopd "^1.0.1" @@ -2577,19 +2670,23 @@ es-abstract@^1.19.0, es-abstract@^1.20.4: is-regex "^1.1.4" is-shared-array-buffer "^1.0.2" is-string "^1.0.7" - is-typed-array "^1.1.10" + is-typed-array "^1.1.12" is-weakref "^1.0.2" object-inspect "^1.12.3" object-keys "^1.1.1" object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" + regexp.prototype.flags "^1.5.1" + safe-array-concat "^1.0.1" safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.7" - string.prototype.trimend "^1.0.6" - string.prototype.trimstart "^1.0.6" + string.prototype.trim "^1.2.8" + string.prototype.trimend "^1.0.7" + string.prototype.trimstart "^1.0.7" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" typed-array-length "^1.0.4" unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" + which-typed-array "^1.1.11" es-array-method-boxes-properly@^1.0.0: version "1.0.0" @@ -2654,18 +2751,18 @@ eslint-config-standard@17.0.0: integrity sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg== eslint-import-resolver-node@^0.3.7: - version "0.3.7" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" - integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== dependencies: debug "^3.2.7" - is-core-module "^2.11.0" - resolve "^1.22.1" + is-core-module "^2.13.0" + resolve "^1.22.4" eslint-module-utils@^2.7.4: - version "2.7.4" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== dependencies: debug "^3.2.7" @@ -2718,9 +2815,9 @@ eslint-plugin-promise@6.1.1: integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== eslint-scope@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" - integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" @@ -2749,10 +2846,10 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz#c7f0f956124ce677047ddbc192a68f999454dedc" - integrity sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.0, eslint-visitor-keys@^3.4.1: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== eslint@8.38.0: version "8.38.0" @@ -2800,14 +2897,14 @@ eslint@8.38.0: strip-json-comments "^3.1.0" text-table "^0.2.0" -espree@^9.5.1: - version "9.5.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.1.tgz#4f26a4d5f18905bf4f2e0bd99002aab807e96dd4" - integrity sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg== +espree@^9.5.1, espree@^9.6.0: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^8.8.0" + acorn "^8.9.0" acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.0" + eslint-visitor-keys "^3.4.1" esprima@2.7.x, esprima@^2.7.1: version "2.7.3" @@ -2849,23 +2946,21 @@ esutils@^2.0.2: integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== eth-gas-reporter@^0.2.25: - version "0.2.25" - resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz#546dfa946c1acee93cb1a94c2a1162292d6ff566" - integrity sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ== + version "0.2.27" + resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.27.tgz#928de8548a674ed64c7ba0bf5795e63079150d4e" + integrity sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw== dependencies: - "@ethersproject/abi" "^5.0.0-beta.146" "@solidity-parser/parser" "^0.14.0" + axios "^1.5.1" cli-table3 "^0.5.0" colors "1.4.0" ethereum-cryptography "^1.0.3" - ethers "^4.0.40" + ethers "^5.7.2" fs-readdir-recursive "^1.1.0" lodash "^4.17.14" markdown-table "^1.1.3" - mocha "^7.1.1" + mocha "^10.2.0" req-cwd "^2.0.0" - request "^2.88.0" - request-promise-native "^1.0.5" sha1 "^1.1.1" sync-request "^6.0.0" @@ -2907,6 +3002,16 @@ ethereum-cryptography@^1.0.3, ethereum-cryptography@^1.1.2: "@scure/bip32" "1.1.5" "@scure/bip39" "1.1.1" +ethereum-cryptography@^2.0.0, ethereum-cryptography@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz#18fa7108622e56481157a5cb7c01c0c6a672eb67" + integrity sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug== + dependencies: + "@noble/curves" "1.1.0" + "@noble/hashes" "1.3.1" + "@scure/bip32" "1.3.1" + "@scure/bip39" "1.2.1" + ethereumjs-abi@^0.6.8: version "0.6.8" resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" @@ -2915,7 +3020,7 @@ ethereumjs-abi@^0.6.8: bn.js "^4.11.8" ethereumjs-util "^6.0.0" -ethereumjs-util@7.1.5, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.4: +ethereumjs-util@7.1.5, ethereumjs-util@^7.1.4: version "7.1.5" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== @@ -2975,7 +3080,7 @@ ethers@5.7.1: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" -ethers@5.7.2, ethers@^5.3.1, ethers@^5.5.3, ethers@^5.6.1, ethers@^5.7.1: +ethers@5.7.2, ethers@^5.3.1, ethers@^5.5.3, ethers@^5.6.1, ethers@^5.7.1, ethers@^5.7.2: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -3011,21 +3116,6 @@ ethers@5.7.2, ethers@^5.3.1, ethers@^5.5.3, ethers@^5.6.1, ethers@^5.7.1: "@ethersproject/web" "5.7.1" "@ethersproject/wordlists" "5.7.0" -ethers@^4.0.40: - version "4.0.49" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894" - integrity sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg== - dependencies: - aes-js "3.0.0" - bn.js "^4.11.9" - elliptic "6.5.4" - hash.js "1.1.3" - js-sha3 "0.5.7" - scrypt-js "2.0.4" - setimmediate "1.0.4" - uuid "2.0.1" - xmlhttprequest "1.8.0" - ethjs-unit@0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" @@ -3055,35 +3145,20 @@ evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-diff@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== fast-glob@^3.0.3: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -3145,11 +3220,12 @@ find-up@^2.1.0: locate-path "^2.0.0" flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + version "3.1.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" + integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== dependencies: - flatted "^3.1.0" + flatted "^3.2.9" + keyv "^4.5.3" rimraf "^3.0.2" flat@^4.1.0: @@ -3164,10 +3240,10 @@ flat@^5.0.2: resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== +flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== fmix@^0.1.0: version "0.1.0" @@ -3177,9 +3253,9 @@ fmix@^0.1.0: imul "^1.0.0" follow-redirects@^1.12.1, follow-redirects@^1.14.0, follow-redirects@^1.15.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + version "1.15.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" + integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== for-each@^0.3.3: version "0.3.3" @@ -3188,11 +3264,6 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== - form-data@^2.2.0: version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -3211,15 +3282,6 @@ form-data@^4.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - fp-ts@1.19.3: version "1.19.3" resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" @@ -3289,31 +3351,31 @@ fsevents@~2.1.1: integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== +function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== -functions-have-names@^1.2.2: +functions-have-names@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== @@ -3323,18 +3385,19 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== +get-func-name@^2.0.0, get-func-name@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== dependencies: function-bind "^1.1.1" has "^1.0.3" + has-proto "^1.0.1" has-symbols "^1.0.3" get-port@^3.1.0: @@ -3350,13 +3413,6 @@ get-symbol-description@^1.0.0: call-bind "^1.0.2" get-intrinsic "^1.1.1" -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== - dependencies: - assert-plus "^1.0.0" - ghost-testrpc@^0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" @@ -3454,9 +3510,9 @@ global-prefix@^3.0.0: which "^1.3.1" globals@^13.19.0: - version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + version "13.23.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" + integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== dependencies: type-fest "^0.20.2" @@ -3504,30 +3560,17 @@ growl@1.10.5: integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== handlebars@^4.0.1, handlebars@^4.7.7: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== dependencies: minimist "^1.2.5" - neo-async "^2.6.0" + neo-async "^2.6.2" source-map "^0.6.1" wordwrap "^1.0.0" optionalDependencies: uglify-js "^3.1.4" -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - hardhat-dependency-compiler@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/hardhat-dependency-compiler/-/hardhat-dependency-compiler-1.1.3.tgz#1e49e23f68878bd713f860c66648a711bc4a4a79" @@ -3737,11 +3780,9 @@ has-tostringtag@^1.0.0: has-symbols "^1.0.2" has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" + version "1.0.4" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6" + integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ== hash-base@^3.0.0: version "3.1.0" @@ -3752,14 +3793,6 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" -hash.js@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" - integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.0" - hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" @@ -3815,15 +3848,6 @@ http-response-object@^3.0.1: dependencies: "@types/node" "^10.0.3" -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -3850,11 +3874,11 @@ ignore@^5.1.1, ignore@^5.2.0, ignore@^5.2.4: integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== immutable@^4.0.0-rc.12: - version "4.3.0" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.0.tgz#eb1738f14ffb39fd068b1dbe1296117484dd34be" - integrity sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg== + version "4.3.4" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.4.tgz#2e07b33837b4bb7662f288c244d1ced1ef65a78f" + integrity sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA== -import-fresh@^3.0.0, import-fresh@^3.2.1: +import-fresh@^3.0.0, import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -3962,10 +3986,10 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.11.0, is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== +is-core-module@^2.11.0, is-core-module@^2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" + integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== dependencies: has "^1.0.3" @@ -4059,21 +4083,12 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typed-array@^1.1.10, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== +is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + which-typed-array "^1.1.11" is-unicode-supported@^0.1.0: version "0.1.0" @@ -4092,6 +4107,11 @@ isarray@0.0.1: resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -4102,20 +4122,10 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== - js-sdsl@^4.1.4: - version "4.4.0" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.0.tgz#8b437dbe642daa95760400b602378ed8ffea8430" - integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== - -js-sha3@0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== + version "4.4.2" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" + integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" @@ -4150,10 +4160,10 @@ js-yaml@4.1.0, js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== json-parse-even-better-errors@^2.3.0: version "2.3.1" @@ -4170,21 +4180,11 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - json5@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" @@ -4225,25 +4225,22 @@ jsonschema@^1.2.4: resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - keccak@^3.0.0, keccak@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276" - integrity sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ== + version "3.0.4" + resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.4.tgz#edc09b89e633c0549da444432ecf062ffadee86d" + integrity sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q== dependencies: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" readable-stream "^3.6.0" +keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" @@ -4331,7 +4328,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.21: +lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4351,7 +4348,7 @@ log-symbols@4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -loupe@^2.3.1: +loupe@^2.3.1, loupe@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== @@ -4420,6 +4417,11 @@ merge2@^1.2.3, merge2@^1.3.0: resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +micro-ftch@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/micro-ftch/-/micro-ftch-0.3.1.tgz#6cb83388de4c1f279a034fb0cf96dfc050853c5f" + integrity sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg== + micromatch@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -4433,7 +4435,7 @@ mime-db@1.52.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@~2.1.19: +mime-types@^2.1.12: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== @@ -4539,7 +4541,7 @@ mocha@7.1.2: yargs-parser "13.1.2" yargs-unparser "1.6.0" -mocha@^10.0.0: +mocha@^10.0.0, mocha@^10.2.0: version "10.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== @@ -4566,36 +4568,6 @@ mocha@^10.0.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" -mocha@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.2.0.tgz#01cc227b00d875ab1eed03a75106689cfed5a604" - integrity sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - chokidar "3.3.0" - debug "3.2.6" - diff "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "3.0.0" - minimatch "3.0.4" - mkdirp "0.5.5" - ms "2.1.1" - node-environment-flags "1.0.6" - object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" - wide-align "1.1.3" - yargs "13.3.2" - yargs-parser "13.1.2" - yargs-unparser "1.6.0" - module-error@^1.0.1, module-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" @@ -4625,27 +4597,27 @@ murmur-128@^0.2.1: fmix "^0.1.0" imul "^1.0.0" -nan@^2.15.0, nan@^2.16.0: - version "2.17.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== +nan@^2.17.0: + version "2.18.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" + integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== nanoid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== -napi-macros@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" - integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== +napi-macros@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" + integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== -neo-async@^2.6.0: +neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== @@ -4671,16 +4643,16 @@ node-environment-flags@1.0.6: semver "^5.7.0" node-fetch@^2.6.0: - version "2.6.9" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" - integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== dependencies: whatwg-url "^5.0.0" node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" - integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== + version "4.6.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" + integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== nofilter@^3.1.0: version "3.1.0" @@ -4707,11 +4679,6 @@ number-to-bn@1.7.0: bn.js "4.11.6" strip-hex-prefix "1.0.0" -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -4748,23 +4715,24 @@ object.assign@^4.1.4: object-keys "^1.1.1" object.getownpropertydescriptors@^2.0.3: - version "2.1.5" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz#db5a9002489b64eef903df81d6623c07e5b4b4d3" - integrity sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw== + version "2.1.7" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.7.tgz#7a466a356cd7da4ba8b9e94ff6d35c3eeab5d56a" + integrity sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g== dependencies: - array.prototype.reduce "^1.0.5" + array.prototype.reduce "^1.0.6" call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" + safe-array-concat "^1.0.0" object.values@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" - integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" + integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" obliterator@^2.0.0: version "2.0.4" @@ -4791,16 +4759,16 @@ optionator@^0.8.1: word-wrap "~1.2.3" optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" ordinal@^1.0.3: version "1.0.3" @@ -4883,7 +4851,7 @@ parse-cache-control@^1.0.1: resolved "https://registry.yarnpkg.com/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e" integrity sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg== -parse-json@^5.0.0: +parse-json@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== @@ -4939,11 +4907,6 @@ pbkdf2@^3.0.17: safe-buffer "^5.0.1" sha.js "^2.4.8" -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== - picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -4978,11 +4941,16 @@ prettier-plugin-solidity@1.1.3: semver "^7.3.8" solidity-comments-extractor "^0.0.7" -prettier@2.8.7, prettier@^2.8.3: +prettier@2.8.7: version "2.8.7" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.7.tgz#bb79fc8729308549d28fe3a98fce73d2c0656450" integrity sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw== +prettier@^2.8.3: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -5000,11 +4968,6 @@ proxy-from-env@^1.1.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== -psl@^1.1.28: - version "1.9.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" - integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== - pump@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/pump/-/pump-1.0.3.tgz#5dfe8311c33bbf6fc18261f9f34702c47c08a954" @@ -5021,23 +4984,18 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -punycode@^2.1.0, punycode@^2.1.1: +punycode@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== qs@^6.4.0, qs@^6.7.0, qs@^6.9.4: - version "6.11.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.1.tgz#6c29dff97f0c0060765911ba65cbc9764186109f" - integrity sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ== + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== dependencies: side-channel "^1.0.4" -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - queue-microtask@^1.2.2, queue-microtask@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -5120,14 +5078,14 @@ recursive-readdir@^2.2.2: dependencies: minimatch "^3.0.5" -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== +regexp.prototype.flags@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" + integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" + define-properties "^1.2.0" + set-function-name "^2.0.0" regexpp@^3.0.0: version "3.2.0" @@ -5148,48 +5106,6 @@ req-from@^2.0.0: dependencies: resolve-from "^3.0.0" -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.5: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.88.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -5227,12 +5143,12 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.22.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== +resolve@^1.1.6, resolve@^1.22.1, resolve@^1.22.4: + version "1.22.6" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.6.tgz#dd209739eca3aef739c626fea1b4f3c506195362" + integrity sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -5289,6 +5205,16 @@ rustbn.js@~0.2.0: resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== +safe-array-concat@^1.0.0, safe-array-concat@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" + integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + isarray "^2.0.5" + safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -5308,7 +5234,7 @@ safe-regex-test@^1.0.0: get-intrinsic "^1.1.3" is-regex "^1.1.4" -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3", safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -5333,11 +5259,6 @@ sc-istanbul@^0.4.5: which "^1.1.1" wordwrap "^1.0.0" -scrypt-js@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" - integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== - scrypt-js@3.0.1, scrypt-js@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" @@ -5353,19 +5274,19 @@ secp256k1@^4.0.1: node-gyp-build "^4.2.0" semver@^5.5.0, semver@^5.7.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.0.0, semver@^7.3.4, semver@^7.3.8: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" @@ -5381,10 +5302,14 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== -setimmediate@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" - integrity sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog== +set-function-name@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" + integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== + dependencies: + define-data-property "^1.0.1" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.0" setimmediate@^1.0.5: version "1.0.5" @@ -5510,9 +5435,11 @@ solhint@3.4.1: prettier "^2.8.3" solidity-ast@^0.4.38: - version "0.4.46" - resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.46.tgz#d0745172dced937741d07464043564e35b147c59" - integrity sha512-MlPZQfPhjWXqh7YxWcBGDXaPZIfMYCOHYoLEhGDWulNwEPIQQZuB7mA9eP17CU0jY/bGR4avCEUVVpvHtT2gbA== + version "0.4.52" + resolved "https://registry.yarnpkg.com/solidity-ast/-/solidity-ast-0.4.52.tgz#9f1a9abc7e5ba28bbf91146ecd07aec7e70f3c85" + integrity sha512-iOya9BSiB9jhM8Vf40n8lGELGzwrUc57rl5BhfNtJ5cvAaMvRcNlHeAMNvqJJyjoUnczqRbHqdivEqK89du3Cw== + dependencies: + array.prototype.findlast "^1.2.2" solidity-comments-extractor@^0.0.7: version "0.0.7" @@ -5584,30 +5511,15 @@ sprintf-js@~1.0.2: integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== ssh2@^1.11.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.11.0.tgz#ce60186216971e12f6deb553dcf82322498fe2e4" - integrity sha512-nfg0wZWGSsfUe/IBJkXVll3PEZ//YH2guww+mP88gTpuSU4FtZN7zu9JoeTGOyCNx2dTDtT9fOpWwlzyj4uOOw== + version "1.14.0" + resolved "https://registry.yarnpkg.com/ssh2/-/ssh2-1.14.0.tgz#8f68440e1b768b66942c9e4e4620b2725b3555bb" + integrity sha512-AqzD1UCqit8tbOKoj6ztDDi1ffJZ2rV2SwlgrVVrHPkV5vWqGJOVp5pmtj18PunkPJAuKQsnInyKV+/Nb2bUnA== dependencies: - asn1 "^0.2.4" + asn1 "^0.2.6" bcrypt-pbkdf "^1.0.2" optionalDependencies: - cpu-features "~0.0.4" - nan "^2.16.0" - -sshpk@^1.7.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" + cpu-features "~0.0.8" + nan "^2.17.0" stacktrace-parser@^0.1.10: version "0.1.10" @@ -5621,16 +5533,6 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g== - -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - "string-width@^1.0.2 || 2", string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -5657,32 +5559,32 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string.prototype.trim@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533" - integrity sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg== +string.prototype.trim@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" + integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" -string.prototype.trimend@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" - integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== +string.prototype.trimend@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" + integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" -string.prototype.trimstart@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" - integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== +string.prototype.trimstart@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" + integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== dependencies: call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" + define-properties "^1.2.0" + es-abstract "^1.22.1" string_decoder@^1.1.1: version "1.3.0" @@ -5913,14 +5815,6 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -tough-cookie@^2.3.3, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - tr46@~0.0.3: version "0.0.3" resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" @@ -5946,19 +5840,12 @@ tsort@0.0.1: resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" - tweetnacl-util@^0.15.1: version "0.15.1" resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== -tweetnacl@^0.14.3, tweetnacl@~0.14.0: +tweetnacl@^0.14.3: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== @@ -5982,7 +5869,7 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-detect@^4.0.0, type-detect@^4.0.5: +type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== @@ -6002,6 +5889,36 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + typed-array-length@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" @@ -6032,11 +5949,11 @@ unbox-primitive@^1.0.2: which-boxed-primitive "^1.0.2" undici@^5.14.0, undici@^5.4.0: - version "5.21.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.21.0.tgz#b00dfc381f202565ab7f52023222ab862bb2494f" - integrity sha512-HOjK8l6a57b2ZGXOcUsI5NLfoTrfmbOl90ixJDl0AEFG4wgHNDQxtZy15/ZQp7HhjkpaGlp/eneMgtsu1dIlUA== + version "5.25.4" + resolved "https://registry.yarnpkg.com/undici/-/undici-5.25.4.tgz#7d8ef81d94f84cd384986271e5e5599b6dff4296" + integrity sha512-450yJxT29qKMf3aoudzFpIciqpx6Pji3hEWaXqXmanbXF58LTAGCKxcJjxMXWu3iG+Mudgo3ZUfDB6YDFd/dAw== dependencies: - busboy "^1.6.0" + "@fastify/busboy" "^2.0.0" universalify@^0.1.0: version "0.1.2" @@ -6070,38 +5987,20 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== -uuid@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" - integrity sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg== - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - web3-utils@^1.3.6: - version "1.9.0" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.9.0.tgz#7c5775a47586cefb4ad488831be8f6627be9283d" - integrity sha512-p++69rCNNfu2jM9n5+VD/g26l+qkEOQ1m6cfRQCbH8ZRrtquTmrirJMgTmyOoax5a5XRYOuws14aypCOs51pdQ== + version "1.10.2" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.10.2.tgz#361103d28a94d5e2a87ba15d776a62c33303eb44" + integrity sha512-TdApdzdse5YR+5GCX/b/vQnhhbj1KSAtfrDtRW7YS0kcWp1gkJsN62gw6GzCaNTeXookB7UrLtmDUuMv65qgow== dependencies: + "@ethereumjs/util" "^8.1.0" bn.js "^5.2.1" ethereum-bloom-filters "^1.0.6" - ethereumjs-util "^7.1.0" + ethereum-cryptography "^2.1.2" ethjs-unit "0.1.6" number-to-bn "1.7.0" randombytes "^2.1.0" @@ -6132,21 +6031,20 @@ which-boxed-primitive@^1.0.2: is-symbol "^1.0.3" which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== + version "2.0.1" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" + integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== -which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== +which-typed-array@^1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" + integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== dependencies: available-typed-arrays "^1.0.5" call-bind "^1.0.2" for-each "^0.3.3" gopd "^1.0.1" has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" which@1.3.1, which@^1.1.1, which@^1.3.1: version "1.3.1" @@ -6169,10 +6067,10 @@ wide-align@1.1.3: dependencies: string-width "^1.0.2 || 2" -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +word-wrap@~1.2.3: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== wordwrap@^1.0.0: version "1.0.0" @@ -6217,11 +6115,6 @@ ws@^7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== -xmlhttprequest@1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" - integrity sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA== - xtend@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" From c2d4ded9d36f601d26c6af44a742a1169ec1252a Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 24 Oct 2023 14:19:58 +0400 Subject: [PATCH 11/32] Add ResolverMock --- contracts/Settlement.sol | 266 ----------------- contracts/interfaces/IResolver.sol | 13 +- contracts/libraries/DynamicSuffix.sol | 42 --- contracts/libraries/FusionDetails.sol | 349 ----------------------- contracts/libraries/TokensAndAmounts.sol | 25 -- contracts/mocks/FusionDetailsMock.sol | 29 -- contracts/mocks/ResolverMock.sol | 128 ++++++--- contracts/mocks/SettlementMock.sol | 15 - test/FusionDetailsMock.js | 54 ---- test/Settlement.js | 195 +++++++++---- 10 files changed, 229 insertions(+), 887 deletions(-) delete mode 100644 contracts/Settlement.sol delete mode 100644 contracts/libraries/DynamicSuffix.sol delete mode 100644 contracts/libraries/FusionDetails.sol delete mode 100644 contracts/libraries/TokensAndAmounts.sol delete mode 100644 contracts/mocks/FusionDetailsMock.sol delete mode 100644 contracts/mocks/SettlementMock.sol delete mode 100644 test/FusionDetailsMock.js diff --git a/contracts/Settlement.sol b/contracts/Settlement.sol deleted file mode 100644 index e5c70d8c..00000000 --- a/contracts/Settlement.sol +++ /dev/null @@ -1,266 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.19; - -import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import "@1inch/limit-order-protocol-contract/contracts/interfaces/IOrderMixin.sol"; -import "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol"; -import "./interfaces/ISettlement.sol"; -import "./interfaces/IResolver.sol"; -import "./libraries/DynamicSuffix.sol"; -import "./libraries/FusionDetails.sol"; -import "./FeeBankCharger.sol"; - -/** - * @title Settlement contract - * @notice Contract to execute limit orders settlement, created by Fusion mode. - */ -contract Settlement is ISettlement, FeeBankCharger { - using SafeERC20 for IERC20; - using DynamicSuffix for bytes; - using AddressLib for Address; - using FusionDetails for bytes; - - error AccessDenied(); - error ResolverIsNotWhitelisted(); - error WrongInteractionTarget(); - error IncorrectSelector(); - error FusionDetailsMismatch(); - error ResolveFailed(); - - // Flag to indicate that the order is the last one in the chain. No interaction will be invoked after its processing. - bytes1 private constant _FINALIZE_INTERACTION = 0x01; - uint256 private constant _ORDER_FEE_BASE_POINTS = 1e15; - uint256 private constant _BASE_POINTS = 10_000_000; // 100% - uint256 private constant _TAKING_FEE_BASE = 1e9; - uint256 private constant _TAKING_FEE_RATIO_OFFSET = 160; - uint256 private constant _RESOLVER_ADDRESS_BYTES_SIZE = 10; - - IOrderMixin private immutable _limitOrderProtocol; - - - /// @dev Modifier to check if the account is the contract itself. - /// @param account The account to check. - modifier onlyThis(address account) { - if (account != address(this)) revert AccessDenied(); - _; - } - - /// @dev Modifier to check if the caller is the limit order protocol contract. - modifier onlyLimitOrderProtocol { - if (msg.sender != address(_limitOrderProtocol)) revert AccessDenied(); - _; - } - - /** - * @notice Initializes the contract. - * @param limitOrderProtocol The limit order protocol contract. - * @param token The token to charge protocol fees in. - */ - constructor(IOrderMixin limitOrderProtocol, IERC20 token) - FeeBankCharger(token) - { - _limitOrderProtocol = limitOrderProtocol; - } - - /** - * @notice Settles the order - * @param data The order to settle with settlement parameters. - * @return Returns a boolean value indicating the success of the function. - */ - function settleOrders(bytes calldata data) public virtual returns(bool) { - _settleOrder(data, msg.sender, 0, msg.data[:0], IERC20(address(0)), 0); - return true; - } - - /** - * @notice Allows a taker to interact with the order after making amount transfered to taker, - * but before taking amount transfered to maker. - * @dev Calls the resolver contract and approves the token to the limit order protocol. - * Layout of extra data parameter: - * byte1 finalize interaction flag - * byte [M] fusion details (variable length, M) - * byte [N] arbitrary data (variable length, N) - * byte32 resolver address - * byte32 resolverFee - * (byte32,byte32) [L] tokensAndAmounts bytes - * byte32 tokensAndAmounts array length in bytes (the last 32 bytes of calldata) - * @param order The limit order being filled, which caused the interaction. - * @param /extension/ The order extension data. - * @param /orderHash/ The order hash. - * @param taker The taker address. - * @param /makingAmount/ The making amount. - * @param takingAmount The taking amount. - * @param /remainingMakingAmount/ The remaining making amount. - * @param extraData Filling order supplemental data. In the order of layout: - * FINALIZE_INTERACTION flag, {FusionDetails} data, resolver, resolver fee, tokensAndAmounts array. See {DynamicSuffix} for details. - */ - function takerInteraction( - IOrderMixin.Order calldata order, - bytes calldata /* extension */, - bytes32 /* orderHash */, - address taker, - uint256 makingAmount, - uint256 takingAmount, - uint256 /* remainingMakingAmount */, - bytes calldata extraData - ) public override onlyThis(taker) onlyLimitOrderProtocol { - (DynamicSuffix.Data calldata suffix, bytes calldata tokensAndAmounts, bytes calldata args) = extraData.decodeSuffix(); - - bytes calldata fusionDetails = args[1:]; - fusionDetails = fusionDetails[:fusionDetails.detailsLength()]; - - uint256 offeredTakingAmount = takingAmount * (_BASE_POINTS + fusionDetails.rateBump()) / _BASE_POINTS; - Address takingFeeData = fusionDetails.takingFeeData(); - uint256 takingFeeAmount = offeredTakingAmount * takingFeeData.getUint32(_TAKING_FEE_RATIO_OFFSET) / _TAKING_FEE_BASE; - - args = args[1 + fusionDetails.length:]; // remove fusion details - - IERC20 token = IERC20(order.takerAsset.get()); - - address resolver = suffix.resolver.get(); - uint256 resolverFee = suffix.resolverFee + (_ORDER_FEE_BASE_POINTS * fusionDetails.resolverFee() * makingAmount + order.makingAmount - 1) / order.makingAmount; - unchecked { - if (extraData[0] == _FINALIZE_INTERACTION) { - bytes memory allTokensAndAmounts = new bytes(tokensAndAmounts.length + 0x40); - assembly ("memory-safe") { - let ptr := add(allTokensAndAmounts, 0x20) - calldatacopy(ptr, tokensAndAmounts.offset, tokensAndAmounts.length) - ptr := add(ptr, tokensAndAmounts.length) - mstore(ptr, token) - mstore(add(ptr, 0x20), add(offeredTakingAmount, takingFeeAmount)) - } - - _chargeFee(resolver, resolverFee); - uint256 resolversLength = uint8(args[args.length - 1]); - bool success = IResolver(resolver).resolveOrders(allTokensAndAmounts, args[:args.length - 1 - resolversLength * _RESOLVER_ADDRESS_BYTES_SIZE]); - if (!success) revert ResolveFailed(); - } else { - _settleOrder(args, resolver, resolverFee, tokensAndAmounts, token, offeredTakingAmount + takingFeeAmount); - } - } - - if (takingFeeAmount > 0) { - token.safeTransfer(takingFeeData.get(), takingFeeAmount); - } - token.forceApprove(address(_limitOrderProtocol), offeredTakingAmount); - } - - struct FillOrderToArgs { - IOrderMixin.Order order; - bytes32 r; - bytes32 vs; - uint256 amount; - TakerTraits takerTraits; - address target; - bytes interaction; - } - - struct FillContractOrderArgs { - IOrderMixin.Order order; - bytes signature; - uint256 amount; - TakerTraits takerTraits; - address target; - bytes interaction; - } - - /** - * @notice Fetches the interaction from calldata. - * @dev Based on the selector determines calldata type and fetches the interaction. - * @param data The data to process. - * @return interaction Returns the interaction data. - */ - function _getInteraction(bytes calldata data) internal pure returns(bytes calldata interaction) { - bytes4 selector = bytes4(data); - if (selector == IOrderMixin.fillOrderArgs.selector) { - FillOrderToArgs calldata args; - assembly ("memory-safe") { - args := add(data.offset, 4) - } - interaction = args.interaction; - } - else if (selector == IOrderMixin.fillContractOrderArgs.selector) { - FillContractOrderArgs calldata args; - assembly ("memory-safe") { - args := add(data.offset, 4) - } - interaction = args.interaction; - } - else { - revert IncorrectSelector(); - } - } - - /** - * @notice Settles a fusion limit order. - * @dev Extracts interaction and fusion details from arguments, checks the resolver and executes . Also calculates the resolver fee. - * @param args The calldata with fill order args, fusion details and dynamic suffix. - * @param resolver The resolver address. The address is checked against the whitelist, interaction is invoked on it, and fees are charged. - * @param resolverFee The accumulated resolver fee. - * @param tokensAndAmounts The tokens and their respective amounts (from previous recursion steps). - * @param token The taker token. Appended to tokensAndAmounts. - * @param newAmount The taker amount. Appended to tokensAndAmounts. - */ - function _settleOrder( - bytes calldata args, - address resolver, - uint256 resolverFee, - bytes calldata tokensAndAmounts, - IERC20 token, - uint256 newAmount - ) private { - bytes calldata interaction = _getInteraction(args); - bytes calldata fusionDetails = interaction[21:]; - fusionDetails = fusionDetails[:fusionDetails.detailsLength()]; - - if (address(bytes20(interaction)) != address(this)) revert WrongInteractionTarget(); - // salt is the first word in Order struct, and we validate that lower 160 bits of salt are hash of fusionDetails - if (uint256(fusionDetails.computeHash(args)) & type(uint160).max != uint256(bytes32(args[4:])) & type(uint160).max) revert FusionDetailsMismatch(); - if (!fusionDetails.checkResolver(resolver, args)) revert ResolverIsNotWhitelisted(); - - uint256 suffixLength; - unchecked { - suffixLength = DynamicSuffix._STATIC_DATA_SIZE + - tokensAndAmounts.length + - (address(token) != address(0) ? 0x60 : 0x20); - } - IOrderMixin limitOrderProtocol = _limitOrderProtocol; - - assembly ("memory-safe") { - let resolversBytesSize := add(1, mul(_RESOLVER_ADDRESS_BYTES_SIZE, byte(0, calldataload(sub(add(args.offset, args.length), 1))))) - let interactionOffset := sub(interaction.offset, args.offset) - - // Copy calldata and patch interaction.length - let ptr := mload(0x40) - calldatacopy(ptr, args.offset, args.length) - mstore(add(ptr, sub(interactionOffset, 0x20)), add(add(interaction.length, suffixLength), resolversBytesSize)) - - let offset := add(add(ptr, interactionOffset), interaction.length) - // Append resolvers - calldatacopy(offset, sub(add(args.offset, args.length), resolversBytesSize), resolversBytesSize) - offset := add(offset, resolversBytesSize) - // Append suffix fields - mstore(offset, resolver) - mstore(add(offset, 0x20), resolverFee) - calldatacopy(add(offset, 0x40), tokensAndAmounts.offset, tokensAndAmounts.length) - - let pointer := add(offset, add(0x40, tokensAndAmounts.length)) - switch token - case 0 { - mstore(pointer, 0) - } - default { - mstore(pointer, token) - mstore(add(pointer, 0x20), newAmount) - mstore(add(pointer, 0x40), add(tokensAndAmounts.length, 0x40)) - } - - // Call fillOrderTo - if iszero(call(gas(), limitOrderProtocol, 0, ptr, add(add(args.length, suffixLength), resolversBytesSize), 0, 0)) { - returndatacopy(ptr, 0, returndatasize()) - revert(ptr, returndatasize()) - } - } - } -} diff --git a/contracts/interfaces/IResolver.sol b/contracts/interfaces/IResolver.sol index 17f5fcc5..9f0abc95 100644 --- a/contracts/interfaces/IResolver.sol +++ b/contracts/interfaces/IResolver.sol @@ -2,6 +2,17 @@ pragma solidity 0.8.19; +import "@1inch/limit-order-protocol-contract/contracts/interfaces/IOrderMixin.sol"; + interface IResolver { - function resolveOrders(bytes calldata tokensAndAmounts, bytes calldata data) external returns(bool); + function takerInteraction( + IOrderMixin.Order calldata order, + bytes calldata extension, + bytes32 orderHash , + address taker, + uint256 makingAmount, + uint256 takingAmount, + uint256 remainingMakingAmount, + bytes calldata extraData + ) external; } diff --git a/contracts/libraries/DynamicSuffix.sol b/contracts/libraries/DynamicSuffix.sol deleted file mode 100644 index 6ba712cf..00000000 --- a/contracts/libraries/DynamicSuffix.sol +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.19; - -import "@1inch/solidity-utils/contracts/libraries/AddressLib.sol"; - -/// @title Library to parse DynamicSuffix from calldata -library DynamicSuffix { - struct Data { - Address resolver; - uint256 resolverFee; - } - - uint256 internal constant _STATIC_DATA_SIZE = 0x40; - - /** - * @notice Decodes calldata passed to settlement function and returns suffix (resolver, resolverFee) and tokensAndAmounts array. - * @dev The function reads only the tail of the calldata, as a dynamic suffix. The calldata before the suffix can be arbitrary, - * and is loaded into args return parameter. - * The dynamic suffix structure is: - * byte32 resolver address - * byte32 resolverFee - * (byte32,byte32) [M] tokensAndAmounts bytes - * byte32 tokensAndAmounts array length in bytes (the last 32 bytes of calldata) - * @param cd Calldata passed to settlement function. - * @return suffix Dynamic suffix (resolver, resolverFee). - * resolverFee is the accumulated fee paid by the resolver for a sequence of fills. - * @return tokensAndAmounts calldata containing tokensAndAmounts. - * @return args calldata containing fusion details. - */ - function decodeSuffix(bytes calldata cd) internal pure returns(Data calldata suffix, bytes calldata tokensAndAmounts, bytes calldata args) { - assembly ("memory-safe") { - let lengthOffset := sub(add(cd.offset, cd.length), 0x20) // length is stored in the last 32 bytes of calldata - tokensAndAmounts.length := calldataload(lengthOffset) // loads tokensAndAmounts array length in bytes - tokensAndAmounts.offset := sub(lengthOffset, tokensAndAmounts.length) // loads tokensAndAmounts array - - suffix := sub(tokensAndAmounts.offset, _STATIC_DATA_SIZE) // loads suffix (resolver, resolverFee) struct - args.offset := cd.offset // loads calldata without suffix into args - args.length := sub(suffix, args.offset) - } - } -} diff --git a/contracts/libraries/FusionDetails.sol b/contracts/libraries/FusionDetails.sol deleted file mode 100644 index a8b3b38d..00000000 --- a/contracts/libraries/FusionDetails.sol +++ /dev/null @@ -1,349 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.19; - -import "@1inch/solidity-utils/contracts/libraries/AddressLib.sol"; - -/// @title Library to parse FusionDetails from calldata -/// @dev Placed in the end of the order interactions data -/// Last byte contains flags and lengths, can have up to 15 resolvers and 7 points -/// Fusion order `interaction` prefix structure: -/// struct Data { -/// bytes1 flags; -/// bytes4 startTime; -/// bytes2 auctionDelay; -/// bytes3 auctionDuration; -/// bytes3 initialRateBump; -/// bytes4 resolverFee; -/// bytes2 publicTimeDelay; -/// (bytes1,bytes2)[N] resolversIndicesAndTimeDeltas; -/// (bytes3,bytes2)[M] pointsAndTimeDeltas; -/// bytes24? takingFeeData; optional, present only if flags has _HAS_TAKING_FEE_FLAG -/// } -library FusionDetails { - uint256 private constant _HAS_TAKING_FEE_FLAG = 0x80; - uint256 private constant _TAKING_FEE_FLAG_BIT_SHIFT = 7; - uint256 private constant _RESOLVERS_LENGTH_MASK = 0x78; - uint256 private constant _RESOLVERS_LENGTH_BIT_SHIFT = 3; - uint256 private constant _POINTS_LENGTH_MASK = 0x07; - - uint256 private constant _TAKING_FEE_DATA_BYTES_SIZE = 24; - uint256 private constant _TAKING_FEE_DATA_BIT_SHIFT = 64; // 256 - _TAKING_FEE_DATA_BYTES_SIZE * 8 - - uint256 private constant _START_TIME_BYTES_OFFSET = 1; - // uint256 private constant _START_TIME_BYTES_SIZE = 4; - uint256 private constant _START_TIME_BIT_SHIFT = 224; // 256 - _START_TIME_BYTES_SIZE * 8 - - uint256 private constant _AUCTION_DELAY_BYTES_OFFSET = 5; // _START_TIME_BYTES_OFFSET + _START_TIME_BYTES_SIZE - // uint256 private constant _AUCTION_DELAY_BYTES_SIZE = 2; - uint256 private constant _AUCTION_DELAY_BIT_SHIFT = 240; // 256 - _AUCTION_DELAY_BYTES_SIZE * 8 - - uint256 private constant _AUCTION_DURATION_BYTES_OFFSET = 7; // _AUCTION_DELAY_BYTES_OFFSET + _AUCTION_DELAY_BYTES_SIZE - // uint256 private constant _AUCTION_DURATION_BYTES_SIZE = 3; - uint256 private constant _AUCTION_DURATION_BIT_SHIFT = 232; // 256 - _AUCTION_DURATION_BYTES_SIZE * 8 - - uint256 private constant _INITIAL_RATE_BUMP_BYTES_OFFSET = 10; // _AUCTION_DURATION_BYTES_OFFSET + _AUCTION_DURATION_BYTES_SIZE - // uint256 private constant _INITIAL_RATE_BUMP_BYTES_SIZE = 3; - uint256 private constant _INITIAL_RATE_BUMP_BIT_SHIFT = 232; // 256 - _INITIAL_RATE_BUMP_BYTES_SIZE * 8 - - uint256 private constant _RESOLVER_FEE_BYTES_OFFSET = 13; // _INITIAL_RATE_BUMP_BYTES_OFFSET + _INITIAL_RATE_BUMP_BYTES_SIZE - // uint256 private constant _RESOLVER_FEE_BYTES_SIZE = 4; - uint256 private constant _RESOLVER_FEE_BIT_SHIFT = 224; // 256 - _RESOLVER_FEE_BYTES_SIZE * 8 - - uint256 private constant _PUBLIC_TIME_DELAY_BYTES_OFFSET = 17; // _RESOLVER_FEE_BYTES_OFFSET + _RESOLVER_FEE_BYTES_SIZE - // uint256 private constant _PUBLIC_TIME_DELAY_BYTES_SIZE = 2; - uint256 private constant _PUBLIC_TIME_DELAY_BIT_SHIFT = 240; // 256 - _PUBLIC_TIME_DELAY_BYTES_SIZE * 8 - - uint256 private constant _RESOLVERS_LIST_BYTES_OFFSET = 19; // _PUBLIC_TIME_DELAY_BYTES_OFFSET + _PUBLIC_TIME_DELAY_BYTES_SIZE - - uint256 private constant _AUCTION_POINT_BUMP_BYTES_SIZE = 3; - uint256 private constant _AUCTION_POINT_DELTA_BYTES_SIZE = 2; - uint256 private constant _AUCTION_POINT_BYTES_SIZE = 5; // _AUCTION_POINT_BUMP_BYTES_SIZE + _AUCTION_POINT_DELTA_BYTES_SIZE; - uint256 private constant _AUCTION_POINT_BUMP_BIT_SHIFT = 232; // 256 - _AUCTION_POINT_BUMP_BYTES_SIZE * 8; - uint256 private constant _AUCTION_POINT_DELTA_BIT_SHIFT = 216; // 256 - (_AUCTION_POINT_DELTA_BYTES_SIZE + _AUCTION_POINT_BUMP_BYTES_SIZE) * 8; - uint256 private constant _AUCTION_POINT_DELTA_MASK = 0xffff; - - uint256 private constant _RESOLVER_INDEX_BYTES_SIZE = 1; - uint256 private constant _RESOLVER_DELTA_BYTES_SIZE = 2; - uint256 private constant _RESOLVER_ADDRESS_BYTES_SIZE = 10; - uint256 private constant _RESOLVER_ADDRESS_MASK = 0xffffffffffffffffffff; - uint256 private constant _RESOLVER_BYTES_SIZE = 3; // _RESOLVER_DELTA_BYTES_SIZE + _RESOLVER_INDEX_BYTES_SIZE; - uint256 private constant _RESOLVER_DELTA_BIT_SHIFT = 240; // 256 - _RESOLVER_DELTA_BYTES_SIZE * 8; - uint256 private constant _RESOLVER_ADDRESS_BIT_SHIFT = 176; // 256 - _RESOLVER_ADDRESS_BYTES_SIZE * 8; - - error InvalidDetailsLength(); - error InvalidWhitelistStructure(); - - /** - * @notice Calculates fusion details calldata length passed to settlement function. - * @param details Fusion details. - * @return len Fusion details calldata length. - */ - function detailsLength(bytes calldata details) internal pure returns (uint256 len) { - assembly ("memory-safe") { - let flags := byte(0, calldataload(details.offset)) - let resolversCount := shr(_RESOLVERS_LENGTH_BIT_SHIFT, and(flags, _RESOLVERS_LENGTH_MASK)) - let pointsCount := and(flags, _POINTS_LENGTH_MASK) - // length = resolver list offset + (resolvers count * resolversSize + points count * point size + taking fee flag * taking fee size) - len := add( - _RESOLVERS_LIST_BYTES_OFFSET, - add( - add( - mul(resolversCount, _RESOLVER_BYTES_SIZE), - mul(pointsCount, _AUCTION_POINT_BYTES_SIZE) - ), - mul(_TAKING_FEE_DATA_BYTES_SIZE, shr(_TAKING_FEE_FLAG_BIT_SHIFT, flags)) - ) - ) - } - - if (details.length < len) revert InvalidDetailsLength(); - } - - /** - * @notice Decodes fusion details calldata and returns fee recipient address and fee amount. - * @dev The taking fee data structure (24 bytes) is: - * bytes4 taking fee - * bytes20 taking fee recipient - * @param details Fusion details calldata. - * @return data Returns taking fee and taking fee recipient address, or `address(0)` if there is no fee. - */ - function takingFeeData(bytes calldata details) internal pure returns (Address data) { - assembly ("memory-safe") { - if and(_HAS_TAKING_FEE_FLAG, byte(0, calldataload(details.offset))) { - let ptr := sub(add(details.offset, details.length), _TAKING_FEE_DATA_BYTES_SIZE) // offset + length - taking fee data size - data := shr(_TAKING_FEE_DATA_BIT_SHIFT, calldataload(ptr)) - } - } - } - - /** - * @notice Computes a Keccak-256 hash over the fusion details data. - * The computation is done by reconstructing the data and hashing it. - * The reconstruction involves: - * - The first part of the fusion details data up to the resolvers list - * - For each resolver, delta is combined with a resolver address from the interaction data - * - The rest of the details data including the auction points and optionally the taking fee and recipient - * @dev The calldata structure for hash function is: - * bytes1 flags; - * bytes4 startTime; - * bytes2 auctionDelay; - * bytes3 auctionDuration; - * bytes3 initialRateBump; - * bytes4 resolverFee; - * bytes2 publicTimeDelay; - * (bytes10,bytes2)[N] resolverAddress (first 10 bytes), resolverDelta; - * (bytes3,bytes2) [M] pointsAndTimeDeltas; - * bytes24? takingFeeData; only present if flags has _HAS_TAKING_FEE_FLAG - * @param details The fusion details calldata - * @param interaction The interaction calldata containing the resolver address - * @return detailsHash The computed Keccak-256 hash over the reconstructed data - */ - function computeHash(bytes calldata details, bytes calldata interaction) internal pure returns (bytes32 detailsHash) { - bytes4 invalidWhitelistStructureError = InvalidWhitelistStructure.selector; - assembly ("memory-safe") { - let flags := byte(0, calldataload(details.offset)) - let resolversCount := shr(_RESOLVERS_LENGTH_BIT_SHIFT, and(flags, _RESOLVERS_LENGTH_MASK)) - let pointsCount := and(flags, _POINTS_LENGTH_MASK) - // pointer to the first resolver address in the list - let addressPtr := sub(add(interaction.offset, interaction.length), 1) - let arraySize := byte(0, calldataload(addressPtr)) - addressPtr := sub(addressPtr, mul(_RESOLVER_ADDRESS_BYTES_SIZE, arraySize)) - // addressPtr = offset + length - 1 - resolver index * resolver address size - if lt(addressPtr, interaction.offset) { - mstore(0, invalidWhitelistStructureError) - revert(0, 4) - } - - let ptr := mload(0x40) - let reconstructed := ptr - calldatacopy(ptr, details.offset, _RESOLVERS_LIST_BYTES_OFFSET) - ptr := add(ptr, _RESOLVERS_LIST_BYTES_OFFSET) - - let cdPtr := add(details.offset, _RESOLVERS_LIST_BYTES_OFFSET) - // for each resolver - for { let cdEnd := add(cdPtr, mul(_RESOLVER_BYTES_SIZE, resolversCount)) } lt(cdPtr, cdEnd) {} { - let resolverIndex := byte(0, calldataload(cdPtr)) - if iszero(lt(resolverIndex, arraySize)) { - mstore(0, invalidWhitelistStructureError) - revert(0, 4) - } - cdPtr := add(cdPtr, _RESOLVER_INDEX_BYTES_SIZE) - let deltaRaw := calldataload(cdPtr) - cdPtr := add(cdPtr, _RESOLVER_DELTA_BYTES_SIZE) - let resolverRaw := calldataload(add(addressPtr, mul(resolverIndex, _RESOLVER_ADDRESS_BYTES_SIZE))) - - mstore(ptr, resolverRaw) - ptr := add(ptr, _RESOLVER_ADDRESS_BYTES_SIZE) - mstore(ptr, deltaRaw) - ptr := add(ptr, _RESOLVER_DELTA_BYTES_SIZE) - } - let takingFeeAndRecipientLength := mul(_TAKING_FEE_DATA_BYTES_SIZE, shr(_TAKING_FEE_FLAG_BIT_SHIFT, flags)) - let pointsAndtakingFeeInfoLength := add(mul(pointsCount, _AUCTION_POINT_BYTES_SIZE), takingFeeAndRecipientLength) - calldatacopy(ptr, cdPtr, pointsAndtakingFeeInfoLength) - ptr := add(ptr, pointsAndtakingFeeInfoLength) - mstore(0x40, ptr) - - let len := sub(ptr, reconstructed) - detailsHash := keccak256(reconstructed, len) - } - } - - /** - * @notice Checks whether a given resolver is valid at the current timestamp. - * - * A resolver is considered valid if the current timestamp is greater than - * the sum of the auction start time and the public time delay. - * - * If the resolver is not valid at this point, the function iterates over the resolvers list. - * If a resolver's address matches the provided address and the current timestamp is greater - * than its start time, the resolver is considered valid. - * - * @param details The calldata representing the fusion details - * @param resolver The address of the resolver to be checked - * @param interaction The calldata representing the interactions to be used for callback addresses - * @return valid Returns true if the resolver is valid at the current timestamp, false otherwise - */ - function checkResolver(bytes calldata details, address resolver, bytes calldata interaction) internal view returns (bool valid) { - bytes4 invalidWhitelistStructureError = InvalidWhitelistStructure.selector; - assembly ("memory-safe") { - let flags := byte(0, calldataload(details.offset)) - let resolversCount := shr(_RESOLVERS_LENGTH_BIT_SHIFT, and(flags, _RESOLVERS_LENGTH_MASK)) - - // Check public time limit - let startTime := shr(_START_TIME_BIT_SHIFT, calldataload(add(details.offset, _START_TIME_BYTES_OFFSET))) - let publicTimeDelay := shr(_PUBLIC_TIME_DELAY_BIT_SHIFT, calldataload(add(details.offset, _PUBLIC_TIME_DELAY_BYTES_OFFSET))) - valid := gt(timestamp(), add(startTime, publicTimeDelay)) - - // Check resolvers and corresponding time limits - if iszero(valid) { - let resolverTimeStart := startTime - let ptr := add(details.offset, _RESOLVERS_LIST_BYTES_OFFSET) // moves pointer to the start of the resolvers list - let addressPtr := sub(add(interaction.offset, interaction.length), 1) // moves address pointer to the resolvers array length - let arraySize := byte(0, calldataload(addressPtr)) - addressPtr := sub(addressPtr, mul(_RESOLVER_ADDRESS_BYTES_SIZE, arraySize)) // moves address pointer to the first resolver address - if lt(addressPtr, interaction.offset) { - mstore(0, invalidWhitelistStructureError) - revert(0, 4) - } - - for { let end := add(ptr, mul(_RESOLVER_BYTES_SIZE, resolversCount)) } lt(ptr, end) { } { - let resolverIndex := byte(0, calldataload(ptr)) // gets resolver's index - if iszero(lt(resolverIndex, arraySize)) { - mstore(0, invalidWhitelistStructureError) - revert(0, 4) - } - ptr := add(ptr, _RESOLVER_INDEX_BYTES_SIZE) // moves pointer to the resolver's delta - resolverTimeStart := add(resolverTimeStart, shr(_RESOLVER_DELTA_BIT_SHIFT, calldataload(ptr))) // gets resolver's time limit - ptr := add(ptr, _RESOLVER_DELTA_BYTES_SIZE) // moves pointer to the next resolver - - // gets resolver's address and checks if it matches the provided address - let account := shr(_RESOLVER_ADDRESS_BIT_SHIFT, calldataload(add(addressPtr, mul(resolverIndex, _RESOLVER_ADDRESS_BYTES_SIZE)))) - if eq(account, and(resolver, _RESOLVER_ADDRESS_MASK)) { - valid := gt(timestamp(), resolverTimeStart) - break - } - } - } - } - } - - /** - * @notice Calculates and returns the rate bump for an auction at the current time. - * - * If the current time is before the auction's start, the initial rate bump is returned. - * If the current time is after the auction's finish, 0 is returned, meaning there is no rate bump after the auction. - * If the current time is within the auction duration, the rate bump is calculated based on a linear interpolation - * between the auction's points, each having a specific rate bump and delay time. - * - * @param details Calldata containing fusion details - * @return ret Returns the rate bump at the current timestamp - */ - function rateBump(bytes calldata details) internal view returns (uint256 ret) { - uint256 startBump; - uint256 auctionStartTime; - uint256 auctionFinishTime; - assembly ("memory-safe") { - startBump := shr(_INITIAL_RATE_BUMP_BIT_SHIFT, calldataload(add(details.offset, _INITIAL_RATE_BUMP_BYTES_OFFSET))) - auctionStartTime := add( - shr(_START_TIME_BIT_SHIFT, calldataload(add(details.offset, _START_TIME_BYTES_OFFSET))), - shr(_AUCTION_DELAY_BIT_SHIFT, calldataload(add(details.offset, _AUCTION_DELAY_BYTES_OFFSET))) - ) - auctionFinishTime := add(auctionStartTime, shr(_AUCTION_DURATION_BIT_SHIFT, calldataload(add(details.offset, _AUCTION_DURATION_BYTES_OFFSET)))) - } - - if (block.timestamp <= auctionStartTime) { - return startBump; - } else if (block.timestamp >= auctionFinishTime) { - return 0; // Means 0% bump - } - - assembly ("memory-safe") { - function linearInterpolation(t1, t2, v1, v2, t) -> v { - // v = ((t - t1) * v2 + (t2 - t) * v1) / (t2 - t1) - v := div( - add(mul(sub(t, t1), v2), mul(sub(t2, t), v1)), - sub(t2, t1) - ) - } - - // move ptr to the first point - let ptr := add(details.offset, _RESOLVERS_LIST_BYTES_OFFSET) - let pointsCount - { - let flags := byte(0, calldataload(details.offset)) - let resolversCount := shr(_RESOLVERS_LENGTH_BIT_SHIFT, and(flags, _RESOLVERS_LENGTH_MASK)) - ptr := add(ptr, mul(resolversCount, _RESOLVER_BYTES_SIZE)) - pointsCount := and(flags, _POINTS_LENGTH_MASK) - } - - // Check points sequentially - let pointTime := auctionStartTime - let prevBump := startBump - let prevPointTime := pointTime - for { let end := add(ptr, mul(_AUCTION_POINT_BYTES_SIZE, pointsCount)) } lt(ptr, end) { } { - let word := calldataload(ptr) - let bump := shr(_AUCTION_POINT_BUMP_BIT_SHIFT, word) - let delay := and(shr(_AUCTION_POINT_DELTA_BIT_SHIFT, word), _AUCTION_POINT_DELTA_MASK) - ptr := add(ptr, add(_AUCTION_POINT_BUMP_BYTES_SIZE, _AUCTION_POINT_DELTA_BYTES_SIZE)) - pointTime := add(pointTime, delay) - if gt(pointTime, timestamp()) { - // Compute linear interpolation between prevBump and bump based on the time passed: - // prevPointTime now pointTime - // prevBump ??? bump - ret := linearInterpolation( - prevPointTime, - pointTime, - prevBump, - bump, - timestamp() - ) - break - } - prevPointTime := pointTime - prevBump := bump - } - - if iszero(ret) { - ret := linearInterpolation( - prevPointTime, - auctionFinishTime, - prevBump, - 0, - timestamp() - ) - } - } - } - - /** - * @notice Decodes fusion details calldata and returns the fee paid by a resolver for filling the order. - * @param details Fusion details calldata. - * @return fee Fee paid by a resolver for filling the order. - */ - function resolverFee(bytes calldata details) internal pure returns (uint256 fee) { - assembly ("memory-safe") { - fee := shr(_RESOLVER_FEE_BIT_SHIFT, calldataload(add(details.offset, _RESOLVER_FEE_BYTES_OFFSET))) - } - } -} diff --git a/contracts/libraries/TokensAndAmounts.sol b/contracts/libraries/TokensAndAmounts.sol deleted file mode 100644 index 7ec0e0bb..00000000 --- a/contracts/libraries/TokensAndAmounts.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.19; - -import "@1inch/solidity-utils/contracts/libraries/AddressLib.sol"; - -/// @title Library to parse TokensAndAmounts array from calldata -library TokensAndAmounts { - struct Data { - Address token; - uint256 amount; - } - - /** - * @notice Decodes calldata passed to settlement function and returns an array of structs representing token addresses and amounts. - * @param cd Calldata passed to settlement function. - * @return decoded Array of structs representing token addresses and amounts. - */ - function decode(bytes calldata cd) internal pure returns(Data[] calldata decoded) { - assembly ("memory-safe") { - decoded.offset := cd.offset - decoded.length := div(cd.length, 0x40) - } - } -} diff --git a/contracts/mocks/FusionDetailsMock.sol b/contracts/mocks/FusionDetailsMock.sol deleted file mode 100644 index d0f22544..00000000 --- a/contracts/mocks/FusionDetailsMock.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.19; - -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; -import "@1inch/solidity-utils/contracts/libraries/AddressLib.sol"; - -import "../libraries/FusionDetails.sol"; - -contract FusionDetailsMock { - using AddressLib for Address; - using FusionDetails for bytes; - - function parse(bytes calldata details, address resolver, bytes calldata whitelist) external view returns( - uint256 detailsLength, - address takingFeeReceiver, - uint256 takingFeeAmount, - uint256 bump, - uint256 resolverFee, - bool isValidResolver - ) { - detailsLength = details.detailsLength(); - takingFeeReceiver = details.takingFeeData().get(); - takingFeeAmount = details.takingFeeData().getUint32(160); - bump = details.rateBump(); - resolverFee = details.resolverFee(); - isValidResolver = details.checkResolver(resolver, whitelist); - } -} diff --git a/contracts/mocks/ResolverMock.sol b/contracts/mocks/ResolverMock.sol index 2b424faf..57ca75d7 100644 --- a/contracts/mocks/ResolverMock.sol +++ b/contracts/mocks/ResolverMock.sol @@ -2,77 +2,113 @@ pragma solidity 0.8.19; +import "@openzeppelin/contracts/interfaces/IERC1271.sol"; import "../interfaces/IResolver.sol"; import "../interfaces/ISettlement.sol"; -import "../libraries/TokensAndAmounts.sol"; import "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol"; +import "@1inch/solidity-utils/contracts/libraries/ECDSA.sol"; +import "@1inch/limit-order-protocol-contract/contracts/interfaces/IOrderMixin.sol"; -contract ResolverMock is IResolver { +contract ResolverMock is IResolver, IERC1271 { error OnlyOwner(); - error OnlySettlement(); + error NotTaker(); + error OnlyLOP(); error FailedExternalCall(uint256 index, bytes reason); - using TokensAndAmounts for bytes; using SafeERC20 for IERC20; using AddressLib for Address; - ISettlement private immutable _settlement; - address private immutable _limitOrderProtocol; + bytes1 private constant _FINALIZE_INTERACTION = 0x01; + uint256 private constant _RESOLVER_ADDRESS_BYTES_SIZE = 10; + uint256 private constant _BASE_POINTS = 10_000_000; // 100% + uint256 private constant _TAKING_FEE_BASE = 1e9; + uint256 private constant _TAKING_FEE_RATIO_OFFSET = 160; + + + address private immutable _settlementExtension; + IOrderMixin private immutable _lopv4; address private immutable _owner; - constructor(ISettlement settlement, address limitOrderProtocol) { - _settlement = settlement; - _limitOrderProtocol = limitOrderProtocol; + constructor(address settlementExtension, IOrderMixin limitOrderProtocol) { + _settlementExtension = settlementExtension; + _lopv4 = limitOrderProtocol; _owner = msg.sender; } - function settleOrders(bytes calldata data) public { - if (msg.sender != _owner) revert OnlyOwner(); - _settlement.settleOrders(data); + function isValidSignature(bytes32 hash, bytes calldata signature) external view returns (bytes4 magicValue) { + if (ECDSA.recoverOrIsValidSignature(_owner, hash, signature)) { + return IERC1271.isValidSignature.selector; + } + return 0xFFFFFFFF; } - /// @dev High byte of `packing` contains number of permits, each 2 bits from lowest contains length of permit (index in [92,120,148] array) - function settleOrdersWithPermits(bytes calldata data, uint256 packing, bytes calldata packedPermits) external { - _performPermits(packing, packedPermits); - settleOrders(data); + function approve(IERC20 token, address to) external { + if (msg.sender != _owner) revert OnlyOwner(); + token.forceApprove(to, type(uint256).max); } - function resolveOrders(bytes calldata tokensAndAmounts, bytes calldata data) external returns(bool) { - if (msg.sender != address(_settlement)) revert OnlySettlement(); + function settleOrders(bytes calldata data) public { + if (msg.sender != _owner) revert OnlyOwner(); + _settleOrders(data); + } - if (data.length > 0) { - (Address[] memory targets, bytes[] memory calldatas) = abi.decode(data, (Address[], bytes[])); - for (uint256 i = 0; i < targets.length; ++i) { - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory reason) = targets[i].get().call(calldatas[i]); - if (!success) revert FailedExternalCall(i, reason); - } - } + function _settleOrders(bytes calldata data) internal { + (bool success, bytes memory reason) = address(_lopv4).call(data); // abi.encodeWithSelector(_lopv4.fillOrderArgs.selector, data) + if (!success) revert FailedExternalCall(0, reason); + } - TokensAndAmounts.Data[] calldata items = tokensAndAmounts.decode(); - for (uint256 i = 0; i < items.length; i++) { - IERC20(items[i].token.get()).safeTransfer(msg.sender, items[i].amount); - } + /// @dev High byte of `packing` contains number of permits, each 2 bits from lowest contains length of permit (index in [92,120,148] array) + // function settleOrdersWithPermits(bytes calldata data, uint256 packing, bytes calldata packedPermits) external { + // _performPermits(packing, packedPermits); + // settleOrders(data); + // } - return true; - } + function takerInteraction( + IOrderMixin.Order calldata /* order */, + bytes calldata /* extension */, + bytes32 /* orderHash */, + address taker, + uint256 /* makingAmount */, + uint256 /* takingAmount */, + uint256 /* remainingMakingAmount */, + bytes calldata extraData + ) public { + if (msg.sender != address(_lopv4)) revert OnlyLOP(); + if (taker != address(this)) revert NotTaker(); - function _performPermits(uint256 packing, bytes calldata packedPermits) private { unchecked { - uint256 permitsCount = packing >> 248; - uint256 start = 0; - for (uint256 i = 0; i < permitsCount; i++) { - uint256 length = (packing >> (i << 1)) & 0x03; - if (length == 0) length = 112; - else if (length == 1) length = 140; - else if (length == 2) length = 136; - - bytes calldata permit = packedPermits[start:start + length]; - address owner = address(bytes20(permit)); - IERC20 token = IERC20(address(bytes20(permit[20:]))); - token.safePermit(owner, _limitOrderProtocol, permit[40:]); - start += length; + if (extraData[0] == _FINALIZE_INTERACTION) { + if (extraData.length > 1) { + (Address[] memory targets, bytes[] memory calldatas) = abi.decode(extraData[1:], (Address[], bytes[])); + for (uint256 i = 0; i < targets.length; ++i) { + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory reason) = targets[i].get().call(calldatas[i]); + if (!success) revert FailedExternalCall(i, reason); + } + } + } else { + // _lopv4.call(abi.encodeWithSelector(extraData[1:4], args[5:])); + _settleOrders(extraData[1:]); } } } + + // function _performPermits(uint256 packing, bytes calldata packedPermits) private { + // unchecked { + // uint256 permitsCount = packing >> 248; + // uint256 start = 0; + // for (uint256 i = 0; i < permitsCount; i++) { + // uint256 length = (packing >> (i << 1)) & 0x03; + // if (length == 0) length = 112; + // else if (length == 1) length = 140; + // else if (length == 2) length = 136; + + // bytes calldata permit = packedPermits[start:start + length]; + // address owner = address(bytes20(permit)); + // IERC20 token = IERC20(address(bytes20(permit[20:]))); + // token.safePermit(owner, _limitOrderProtocol, permit[40:]); + // start += length; + // } + // } + // } } diff --git a/contracts/mocks/SettlementMock.sol b/contracts/mocks/SettlementMock.sol deleted file mode 100644 index ad93d492..00000000 --- a/contracts/mocks/SettlementMock.sol +++ /dev/null @@ -1,15 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.19; - -import "../Settlement.sol"; - -contract SettlementMock is Settlement { - constructor(IOrderMixin limitOrderProtocol, IERC20 token) - Settlement(limitOrderProtocol, token) - {} - - function decreaseAvailableCreditMock(address account, uint256 amount) external { - _chargeFee(account, amount); - } -} diff --git a/test/FusionDetailsMock.js b/test/FusionDetailsMock.js deleted file mode 100644 index 400a4d76..00000000 --- a/test/FusionDetailsMock.js +++ /dev/null @@ -1,54 +0,0 @@ -const { BigNumber } = require('ethers'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { expect, constants, time, deployContract } = require('@1inch/solidity-utils'); -const { buildFusions } = require('./helpers/fusionUtils'); - -describe('FusionDetailsMock', function () { - async function initContracts() { - const fusionDetailsMock = await deployContract('FusionDetailsMock', []); - return { fusionDetailsMock }; - } - - it('should return default values', async function () { - const { fusionDetailsMock } = await loadFixture(initContracts); - - const { fusions: [fusionDetails], resolvers } = await buildFusions([{}]); - const result = await fusionDetailsMock.parse(fusionDetails, constants.ZERO_ADDRESS, resolvers); - - expect(Object.assign({}, result)).to.deep.contain({ - detailsLength: BigNumber.from('19'), - takingFeeReceiver: constants.ZERO_ADDRESS, - takingFeeAmount: BigNumber.from('0'), - bump: BigNumber.from('0'), - resolverFee: BigNumber.from('0'), - isValidResolver: false, - }); - }); - - it('should return custom values', async function () { - const { fusionDetailsMock } = await loadFixture(initContracts); - - const { fusions: [fusionDetails], resolvers } = await buildFusions([{ - resolvers: [fusionDetailsMock.address], - points: [[10n, 100n], [5n, 50n]], - startTime: (await time.latest()) + 100, - auctionDuration: time.duration.hours(2), - initialRateBump: 200n, - resolverFee: 10000n, - publicTimeDelay: time.duration.hours(1), - }]); - - await time.increase(time.duration.minutes(2)); - - const result = await fusionDetailsMock.parse(fusionDetails, fusionDetailsMock.address, resolvers); - - expect(Object.assign({}, result)).to.deep.include({ - detailsLength: BigNumber.from('32'), - takingFeeReceiver: constants.ZERO_ADDRESS, - takingFeeAmount: BigNumber.from('0'), - bump: BigNumber.from('49'), - resolverFee: BigNumber.from('10000'), - isValidResolver: true, - }); - }); -}); diff --git a/test/Settlement.js b/test/Settlement.js index ffd794c9..dfd0e219 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -2,44 +2,43 @@ const { time, expect, ether, trim0x, timeIncreaseTo, getPermit, getPermit2, comp const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { ethers } = require('hardhat'); const { deploySwapTokens, getChainId } = require('./helpers/fixtures'); -const { buildOrder, signOrder, compactSignature, fillWithMakingAmount, buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); -const { buildFusions } = require('./helpers/fusionUtils'); +const { buildOrder, signOrder, buildTakerTraits, buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); const ORDER_FEE = 100n; const BACK_ORDER_FEE = 125n; const BASE_POINTS = ether('0.001'); // 1e15 -describe.skip('Settlement', function () { +describe('Settlement', function () { async function initContracts() { const abiCoder = ethers.utils.defaultAbiCoder; const chainId = await getChainId(); const [owner, alice, bob] = await ethers.getSigners(); - const { dai, weth, inch, swap } = await deploySwapTokens(); + const { dai, weth, inch, lopv4 } = await deploySwapTokens(); await dai.transfer(alice.address, ether('100')); await inch.mint(owner.address, ether('100')); await weth.deposit({ value: ether('1') }); await weth.connect(alice).deposit({ value: ether('1') }); - const settlement = await deployContract('SettlementMock', [swap.address, inch.address]); + const settlement = await deployContract('SettlementExtensionMock', [lopv4.address, inch.address]); const FeeBank = await ethers.getContractFactory('FeeBank'); const feeBank = FeeBank.attach(await settlement.feeBank()); const ResolverMock = await ethers.getContractFactory('ResolverMock'); - const resolver = await ResolverMock.deploy(settlement.address, swap.address); + const resolver = await ResolverMock.deploy(settlement.address, lopv4.address); await inch.approve(feeBank.address, ether('100')); await feeBank.depositFor(resolver.address, ether('100')); - await dai.approve(swap.address, ether('100')); - await dai.connect(alice).approve(swap.address, ether('100')); - await weth.approve(swap.address, ether('1')); - await weth.connect(alice).approve(swap.address, ether('1')); + await dai.approve(lopv4.address, ether('100')); + await dai.connect(alice).approve(lopv4.address, ether('100')); + await weth.approve(lopv4.address, ether('1')); + await weth.connect(alice).approve(lopv4.address, ether('1')); return { - contracts: { dai, weth, swap, settlement, feeBank, resolver }, + contracts: { dai, weth, lopv4, settlement, feeBank, resolver }, accounts: { owner, alice, bob }, others: { chainId, abiCoder }, }; @@ -56,70 +55,146 @@ describe.skip('Settlement', function () { fillingAmount = orderData.makingAmount, }) { const { - contracts: { swap, settlement, resolver }, + contracts: { lopv4, settlement, resolver }, others: { chainId }, } = dataFormFixture; - const { - fusions: [fusionDetails], - hashes: [fusionHash], - resolvers, - } = await buildFusions([singleFusionData]); - const order = buildOrder(orderData); - order.salt = fusionHash; - const { r, vs } = compactSignature(await signOrder(order, chainId, swap.address, orderSigner)); - const fillOrderToData = swap.interface.encodeFunctionData('fillOrderTo', [ - order, - r, - vs, - fillingAmount, - fillWithMakingAmount('0'), - resolver.address, - settlement.address + (isInnermostOrder ? '01' : '00') + trim0x(fusionDetails) + trim0x(additionalDataForSettlement), - ]); + + const auctionStartTime = await time.latest(); + const auctionDetails = ethers.utils.solidityPack( + ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], + ); + + const order = buildOrder({ + maker: alice.address, + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), + }, { + makingAmountData: settlementExtension.address + trim0x(auctionDetails), + takingAmountData: settlementExtension.address + trim0x(auctionDetails), + postInteraction: settlementExtension.address + trim0x(ethers.utils.solidityPack( + ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + owner.address.substring(22), 0], + )), + }); + + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, lopv4.address, alice)); + + await weth.approve(lopv4.address, ether('0.1')); + + const takerTraits = buildTakerTraits({ + makingAmount: true, + minReturn: ether('0.1'), + extension: order.extension, + }); + + + // const { + // fusions: [fusionDetails], + // hashes: [fusionHash], + // resolvers, + // } = await buildFusions([singleFusionData]); + // const order = buildOrder(orderData); + // order.salt = fusionHash; + // const { r, vs } = compactSignature(await signOrder(order, chainId, lopv4.address, orderSigner)); + // const fillOrderToData = lopv4.interface.encodeFunctionData('fillOrderTo', [ + // order, + // r, + // vs, + // fillingAmount, + // fillWithMakingAmount('0'), + // resolver.address, + // settlement.address + (isInnermostOrder ? '01' : '00') + trim0x(fusionDetails) + trim0x(additionalDataForSettlement), + // ]); return needAddResolvers ? fillOrderToData + trim0x(resolvers) : fillOrderToData; } it('opposite direction recursive swap', async function () { const dataFormFixture = await loadFixture(initContracts); const { - contracts: { dai, weth, settlement, resolver }, + contracts: { dai, weth, lopv4, settlement, resolver }, accounts: { owner, alice }, + others: { chainId }, } = dataFormFixture; - const fillOrderToData1 = await buildCalldataForOrder({ - orderData: { - maker: alice.address, - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.11'), - takingAmount: ether('100'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), - }, - singleFusionData: { resolvers: [resolver.address] }, - orderSigner: alice, - dataFormFixture, - isInnermostOrder: true, + const auctionStartTime = await time.latest(); + const auctionDetails = ethers.utils.solidityPack( + ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], + ); + + const order = buildOrder({ + maker: alice.address, + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), + }, { + makingAmountData: settlement.address + trim0x(auctionDetails), + takingAmountData: settlement.address + trim0x(auctionDetails), + postInteraction: settlement.address + trim0x(ethers.utils.solidityPack( + ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + resolver.address.substring(22), 0], + )), + }); + const backOrder = buildOrder({ + maker: owner.address, + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: ether('0.11'), + takingAmount: ether('100'), + makerTraits: buildMakerTraits(), + }, { + makingAmountData: settlement.address + trim0x(auctionDetails), + takingAmountData: settlement.address + trim0x(auctionDetails), + postInteraction: settlement.address + trim0x(ethers.utils.solidityPack( + ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + resolver.address.substring(22), 0], + )), }); - const fillOrderToData0 = await buildCalldataForOrder({ - orderData: { - maker: owner.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.11'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), - }, - singleFusionData: { resolvers: [resolver.address] }, - orderSigner: owner, - dataFormFixture, - additionalDataForSettlement: fillOrderToData1, - needAddResolvers: true, + const signature = ethers.utils.splitSignature(await signOrder(order, chainId, lopv4.address, alice)); + const signatureBackOrder = ethers.utils.splitSignature(await signOrder(backOrder, chainId, lopv4.address, owner)); + + const orderTakerTraits = buildTakerTraits({ + makingAmount: false, + minReturn: ether('90'), + extension: order.extension, + interaction: resolver.address + '01', + target: resolver.address, }); - const txn = await resolver.settleOrders(fillOrderToData0); - await expect(txn).to.changeTokenBalances(dai, [owner, alice], [ether('-100'), ether('100')]); - await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('0.11'), ether('-0.11')]); + const orderBackTakerTraits = buildTakerTraits({ + makingAmount: false, + minReturn: ether('0.1'), + extension: backOrder.extension, + interaction: resolver.address + '00' + lopv4.interface.encodeFunctionData('fillOrderArgs', [ + order, + signature.r, + signature._vs, + ether('0.1'), + orderTakerTraits.traits, + orderTakerTraits.args, + ]).substring(2), //.substring(10), + target: resolver.address, + }); + + await resolver.approve(dai.address, lopv4.address); + await resolver.approve(weth.address, lopv4.address); + + const tx = await resolver.settleOrders( + // '0x' + + lopv4.interface.encodeFunctionData('fillOrderArgs', [ + backOrder, + signatureBackOrder.r, + signatureBackOrder._vs, + ether('100'), + orderBackTakerTraits.traits, + orderBackTakerTraits.args, + ]), //.substring(10), + ); + + await expect(tx).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('100'), ether('-100'), ether('0')]); + await expect(tx).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('-0.11'), ether('0.1'), ether('0.01')]); }); it('settle orders with permits, permit', async function () { From 606b68dc2cfed3a1899bb88d68a0c509b2b97bc5 Mon Sep 17 00:00:00 2001 From: Denis Date: Tue, 24 Oct 2023 21:15:53 +0400 Subject: [PATCH 12/32] Patch buildCalldataForOrder method in tests for SettlementExt --- test/Settlement.js | 175 ++++++++++++++++----------------------------- 1 file changed, 61 insertions(+), 114 deletions(-) diff --git a/test/Settlement.js b/test/Settlement.js index dfd0e219..e180077f 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -37,161 +37,108 @@ describe('Settlement', function () { await weth.approve(lopv4.address, ether('1')); await weth.connect(alice).approve(lopv4.address, ether('1')); + await resolver.approve(dai.address, lopv4.address); + await resolver.approve(weth.address, lopv4.address); + + const auctionStartTime = await time.latest(); + const auctionDetails = ethers.utils.solidityPack( + ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], + ); + return { contracts: { dai, weth, lopv4, settlement, feeBank, resolver }, accounts: { owner, alice, bob }, - others: { chainId, abiCoder }, + others: { chainId, abiCoder, auctionStartTime, auctionDetails }, }; } async function buildCalldataForOrder({ orderData, - singleFusionData, orderSigner, + minReturn, dataFormFixture, additionalDataForSettlement = '', isInnermostOrder = false, - needAddResolvers = false, + isMakingAmount = true, fillingAmount = orderData.makingAmount, }) { const { contracts: { lopv4, settlement, resolver }, - others: { chainId }, + others: { chainId, auctionStartTime, auctionDetails }, } = dataFormFixture; - const auctionStartTime = await time.latest(); - const auctionDetails = ethers.utils.solidityPack( - ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], - ); - - const order = buildOrder({ - maker: alice.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), - makerTraits: buildMakerTraits(), - }, { - makingAmountData: settlementExtension.address + trim0x(auctionDetails), - takingAmountData: settlementExtension.address + trim0x(auctionDetails), - postInteraction: settlementExtension.address + trim0x(ethers.utils.solidityPack( - ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + owner.address.substring(22), 0], + const order = buildOrder(orderData, { + makingAmountData: settlement.address + trim0x(auctionDetails), + takingAmountData: settlement.address + trim0x(auctionDetails), + postInteraction: settlement.address + trim0x(ethers.utils.solidityPack( + ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + resolver.address.substring(22), 0], )), }); - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, lopv4.address, alice)); + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, lopv4.address, orderSigner)); - await weth.approve(lopv4.address, ether('0.1')); + await resolver.approve(order.takerAsset, lopv4.address); const takerTraits = buildTakerTraits({ - makingAmount: true, - minReturn: ether('0.1'), + isMakingAmount, + minReturn, extension: order.extension, + interaction: resolver.address + (isInnermostOrder ? '01' : '00') + trim0x(additionalDataForSettlement), + target: resolver.address, }); - - // const { - // fusions: [fusionDetails], - // hashes: [fusionHash], - // resolvers, - // } = await buildFusions([singleFusionData]); - // const order = buildOrder(orderData); - // order.salt = fusionHash; - // const { r, vs } = compactSignature(await signOrder(order, chainId, lopv4.address, orderSigner)); - // const fillOrderToData = lopv4.interface.encodeFunctionData('fillOrderTo', [ - // order, - // r, - // vs, - // fillingAmount, - // fillWithMakingAmount('0'), - // resolver.address, - // settlement.address + (isInnermostOrder ? '01' : '00') + trim0x(fusionDetails) + trim0x(additionalDataForSettlement), - // ]); - return needAddResolvers ? fillOrderToData + trim0x(resolvers) : fillOrderToData; + return lopv4.interface.encodeFunctionData('fillOrderArgs', [ + order, + r, + vs, + fillingAmount, + takerTraits.traits, + takerTraits.args, + ]); } it('opposite direction recursive swap', async function () { const dataFormFixture = await loadFixture(initContracts); const { - contracts: { dai, weth, lopv4, settlement, resolver }, + contracts: { dai, weth, resolver }, accounts: { owner, alice }, - others: { chainId }, } = dataFormFixture; - const auctionStartTime = await time.latest(); - const auctionDetails = ethers.utils.solidityPack( - ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], - ); - - const order = buildOrder({ - maker: alice.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), - makerTraits: buildMakerTraits(), - }, { - makingAmountData: settlement.address + trim0x(auctionDetails), - takingAmountData: settlement.address + trim0x(auctionDetails), - postInteraction: settlement.address + trim0x(ethers.utils.solidityPack( - ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + resolver.address.substring(22), 0], - )), - }); - const backOrder = buildOrder({ - maker: owner.address, - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.11'), - takingAmount: ether('100'), - makerTraits: buildMakerTraits(), - }, { - makingAmountData: settlement.address + trim0x(auctionDetails), - takingAmountData: settlement.address + trim0x(auctionDetails), - postInteraction: settlement.address + trim0x(ethers.utils.solidityPack( - ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + resolver.address.substring(22), 0], - )), - }); - - const signature = ethers.utils.splitSignature(await signOrder(order, chainId, lopv4.address, alice)); - const signatureBackOrder = ethers.utils.splitSignature(await signOrder(backOrder, chainId, lopv4.address, owner)); - - const orderTakerTraits = buildTakerTraits({ - makingAmount: false, + const fillOrderToData1 = await buildCalldataForOrder({ + orderData: { + maker: alice.address, + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), + }, + orderSigner: alice, + dataFormFixture, minReturn: ether('90'), - extension: order.extension, - interaction: resolver.address + '01', - target: resolver.address, + isInnermostOrder: true, + isMakingAmount: false, + fillingAmount: ether('0.1'), }); - const orderBackTakerTraits = buildTakerTraits({ - makingAmount: false, + const fillOrderToData0 = await buildCalldataForOrder({ + orderData: { + maker: owner.address, + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: ether('0.11'), + takingAmount: ether('100'), + makerTraits: buildMakerTraits(), + }, + orderSigner: owner, + dataFormFixture, minReturn: ether('0.1'), - extension: backOrder.extension, - interaction: resolver.address + '00' + lopv4.interface.encodeFunctionData('fillOrderArgs', [ - order, - signature.r, - signature._vs, - ether('0.1'), - orderTakerTraits.traits, - orderTakerTraits.args, - ]).substring(2), //.substring(10), - target: resolver.address, + additionalDataForSettlement: fillOrderToData1, + isMakingAmount: false, + fillingAmount: ether('100'), }); - await resolver.approve(dai.address, lopv4.address); - await resolver.approve(weth.address, lopv4.address); - - const tx = await resolver.settleOrders( - // '0x' + - lopv4.interface.encodeFunctionData('fillOrderArgs', [ - backOrder, - signatureBackOrder.r, - signatureBackOrder._vs, - ether('100'), - orderBackTakerTraits.traits, - orderBackTakerTraits.args, - ]), //.substring(10), - ); + const tx = await resolver.settleOrders(fillOrderToData0); await expect(tx).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('100'), ether('-100'), ether('0')]); await expect(tx).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('-0.11'), ether('0.1'), ether('0.01')]); From a7fa6564ce5c0288d5af1034f259eb4b427b5b2a Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 25 Oct 2023 01:13:39 +0400 Subject: [PATCH 13/32] Fix some tests (permits and integrationFee) --- contracts/mocks/ResolverMock.sol | 46 ++++----- test/Settlement.js | 156 ++++++++++++++++++------------- 2 files changed, 113 insertions(+), 89 deletions(-) diff --git a/contracts/mocks/ResolverMock.sol b/contracts/mocks/ResolverMock.sol index 57ca75d7..f8c963d0 100644 --- a/contracts/mocks/ResolverMock.sol +++ b/contracts/mocks/ResolverMock.sol @@ -57,11 +57,11 @@ contract ResolverMock is IResolver, IERC1271 { if (!success) revert FailedExternalCall(0, reason); } - /// @dev High byte of `packing` contains number of permits, each 2 bits from lowest contains length of permit (index in [92,120,148] array) - // function settleOrdersWithPermits(bytes calldata data, uint256 packing, bytes calldata packedPermits) external { - // _performPermits(packing, packedPermits); - // settleOrders(data); - // } + // @dev High byte of `packing` contains number of permits, each 2 bits from lowest contains length of permit (index in [92,120,148] array) + function settleOrdersWithPermits(bytes calldata data, uint256 packing, bytes calldata packedPermits) external { + _performPermits(packing, packedPermits); + settleOrders(data); + } function takerInteraction( IOrderMixin.Order calldata /* order */, @@ -93,22 +93,22 @@ contract ResolverMock is IResolver, IERC1271 { } } - // function _performPermits(uint256 packing, bytes calldata packedPermits) private { - // unchecked { - // uint256 permitsCount = packing >> 248; - // uint256 start = 0; - // for (uint256 i = 0; i < permitsCount; i++) { - // uint256 length = (packing >> (i << 1)) & 0x03; - // if (length == 0) length = 112; - // else if (length == 1) length = 140; - // else if (length == 2) length = 136; - - // bytes calldata permit = packedPermits[start:start + length]; - // address owner = address(bytes20(permit)); - // IERC20 token = IERC20(address(bytes20(permit[20:]))); - // token.safePermit(owner, _limitOrderProtocol, permit[40:]); - // start += length; - // } - // } - // } + function _performPermits(uint256 packing, bytes calldata packedPermits) private { + unchecked { + uint256 permitsCount = packing >> 248; + uint256 start = 0; + for (uint256 i = 0; i < permitsCount; i++) { + uint256 length = (packing >> (i << 1)) & 0x03; + if (length == 0) length = 112; + else if (length == 1) length = 140; + else if (length == 2) length = 136; + + bytes calldata permit = packedPermits[start:start + length]; + address owner = address(bytes20(permit)); + IERC20 token = IERC20(address(bytes20(permit[20:]))); + token.safePermit(owner, address(_lopv4), permit[40:]); + start += length; + } + } + } } diff --git a/test/Settlement.js b/test/Settlement.js index e180077f..c60c87db 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -1,4 +1,4 @@ -const { time, expect, ether, trim0x, timeIncreaseTo, getPermit, getPermit2, compressPermit, permit2Contract, deployContract } = require('@1inch/solidity-utils'); +const { time, expect, ether, trim0x, timeIncreaseTo, getPermit, getPermit2, compressPermit, permit2Contract, deployContract, constants } = require('@1inch/solidity-utils'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { ethers } = require('hardhat'); const { deploySwapTokens, getChainId } = require('./helpers/fixtures'); @@ -16,7 +16,7 @@ describe('Settlement', function () { const { dai, weth, inch, lopv4 } = await deploySwapTokens(); - await dai.transfer(alice.address, ether('100')); + await dai.transfer(alice.address, ether('101')); await inch.mint(owner.address, ether('100')); await weth.deposit({ value: ether('1') }); await weth.connect(alice).deposit({ value: ether('1') }); @@ -61,6 +61,9 @@ describe('Settlement', function () { isInnermostOrder = false, isMakingAmount = true, fillingAmount = orderData.makingAmount, + feeType = 0, + integrator = orderSigner.address, + resolverFee = 0, }) { const { contracts: { lopv4, settlement, resolver }, @@ -70,9 +73,13 @@ describe('Settlement', function () { const order = buildOrder(orderData, { makingAmountData: settlement.address + trim0x(auctionDetails), takingAmountData: settlement.address + trim0x(auctionDetails), - postInteraction: settlement.address + trim0x(ethers.utils.solidityPack( - ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + resolver.address.substring(22), 0], - )), + postInteraction: settlement.address + + ( + feeType == 2 + ? trim0x(ethers.utils.solidityPack(['uint8', 'bytes20', 'bytes4'], [feeType, integrator, '0x' + resolverFee.toString(16).padStart(8, '0')])) + : trim0x(ethers.utils.solidityPack(['uint8', 'bytes4'], [feeType, '0x' + resolverFee.toString(16).padStart(8, '0')])) + ) + + trim0x(ethers.utils.solidityPack(['uint32', 'bytes10', 'uint16'], [auctionStartTime, '0x' + resolver.address.substring(22), 0])), }); const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, lopv4.address, orderSigner)); @@ -138,16 +145,15 @@ describe('Settlement', function () { fillingAmount: ether('100'), }); - const tx = await resolver.settleOrders(fillOrderToData0); - - await expect(tx).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('100'), ether('-100'), ether('0')]); - await expect(tx).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('-0.11'), ether('0.1'), ether('0.01')]); + const txn = await resolver.settleOrders(fillOrderToData0); + await expect(txn).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('100'), ether('-100'), ether('0')]); + await expect(txn).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('-0.11'), ether('0.1'), ether('0.01')]); }); it('settle orders with permits, permit', async function () { const dataFormFixture = await loadFixture(initContracts); const { - contracts: { dai, weth, swap, settlement, resolver }, + contracts: { dai, weth, lopv4, resolver }, accounts: { owner, alice }, others: { chainId }, } = dataFormFixture; @@ -155,48 +161,51 @@ describe('Settlement', function () { const fillOrderToData1 = await buildCalldataForOrder({ orderData: { maker: alice.address, - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.11'), - takingAmount: ether('100'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address] }, orderSigner: alice, dataFormFixture, + minReturn: ether('90'), isInnermostOrder: true, + isMakingAmount: false, + fillingAmount: ether('0.1'), }); const fillOrderToData0 = await buildCalldataForOrder({ orderData: { maker: owner.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.11'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: ether('0.11'), + takingAmount: ether('100'), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address] }, orderSigner: owner, dataFormFixture, + minReturn: ether('0.1'), additionalDataForSettlement: fillOrderToData1, - needAddResolvers: true, + isMakingAmount: false, + fillingAmount: ether('100'), }); - await weth.connect(alice).approve(swap.address, ether('0.11')); - await dai.connect(owner).approve(swap.address, 0n); // remove direct approve - const permit0 = compressPermit(await getPermit(owner, dai, '1', chainId, swap.address, ether('100'))); + await weth.connect(alice).approve(lopv4.address, ether('0.11')); + await dai.connect(owner).approve(lopv4.address, 0n); // remove direct approve + const permit0 = compressPermit(await getPermit(owner, dai, '1', chainId, lopv4.address, ether('100'))); const packing = (1n << 248n) | 1n; const txn = await resolver.settleOrdersWithPermits(fillOrderToData0, packing, owner.address + trim0x(dai.address) + trim0x(permit0)); - await expect(txn).to.changeTokenBalances(dai, [owner, alice], [ether('-100'), ether('100')]); - await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('0.11'), ether('-0.11')]); + await expect(txn).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('100'), ether('-100'), ether('0')]); + await expect(txn).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('-0.11'), ether('0.1'), ether('0.01')]); }); it('settle orders with permits, permit2', async function () { const dataFormFixture = await loadFixture(initContracts); const { - contracts: { dai, weth, swap, settlement, resolver }, + contracts: { dai, weth, lopv4, resolver }, accounts: { owner, alice }, others: { chainId }, } = dataFormFixture; @@ -204,95 +213,110 @@ describe('Settlement', function () { const fillOrderToData1 = await buildCalldataForOrder({ orderData: { maker: alice.address, - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.11'), - takingAmount: ether('100'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address, usePermit2: true }), + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address] }, orderSigner: alice, dataFormFixture, + minReturn: ether('90'), isInnermostOrder: true, + isMakingAmount: false, + fillingAmount: ether('0.1'), }); const fillOrderToData0 = await buildCalldataForOrder({ orderData: { maker: owner.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.11'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address, usePermit2: true }), + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: ether('0.11'), + takingAmount: ether('100'), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address] }, orderSigner: owner, dataFormFixture, + minReturn: ether('0.1'), additionalDataForSettlement: fillOrderToData1, - needAddResolvers: true, + isMakingAmount: false, + fillingAmount: ether('100'), }); const permit2 = await permit2Contract(); await dai.approve(permit2.address, ether('100')); await weth.connect(alice).approve(permit2.address, ether('0.11')); - await dai.connect(owner).approve(swap.address, 0n); // remove direct approve - await weth.connect(alice).approve(swap.address, 0n); // remove direct approve - const permit0 = compressPermit(await getPermit2(owner, dai.address, chainId, swap.address, ether('100'))); - const permit1 = compressPermit(await getPermit2(alice, weth.address, chainId, swap.address, ether('0.11'))); + await dai.connect(owner).approve(lopv4.address, 0n); // remove direct approve + await weth.connect(alice).approve(lopv4.address, 0n); // remove direct approve + const permit0 = compressPermit(await getPermit2(owner, dai.address, chainId, lopv4.address, ether('100'))); + const permit1 = compressPermit(await getPermit2(alice, weth.address, chainId, lopv4.address, ether('0.11'))); const packing = (2n << 248n) | 2n | 8n; const txn = await resolver.settleOrdersWithPermits(fillOrderToData0, packing, owner.address + trim0x(dai.address) + trim0x(permit0) + trim0x(alice.address) + trim0x(weth.address) + trim0x(permit1)); - await expect(txn).to.changeTokenBalances(dai, [owner, alice], [ether('-100'), ether('100')]); - await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('0.11'), ether('-0.11')]); + await expect(txn).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('100'), ether('-100'), ether('0')]); + await expect(txn).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('-0.11'), ether('0.1'), ether('0.01')]); }); it('opposite direction recursive swap with taking fee', async function () { const dataFormFixture = await loadFixture(initContracts); const { - contracts: { dai, weth, settlement, resolver }, + contracts: { dai, weth, resolver, settlement }, accounts: { owner, alice, bob }, } = dataFormFixture; const fillOrderToData1 = await buildCalldataForOrder({ orderData: { maker: alice.address, - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.1'), - takingAmount: ether('100'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address], takerFee: 10000000n, takerFeeReceiver: bob.address }, orderSigner: alice, dataFormFixture, + minReturn: ether('90'), isInnermostOrder: true, + isMakingAmount: false, + fillingAmount: ether('0.1'), + feeType: 2, + integrator: bob.address, + resolverFee: 1000000, }); const fillOrderToData0 = await buildCalldataForOrder({ orderData: { maker: owner.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: ether('0.11'), + takingAmount: ether('100'), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address], takerFee: 10000000n, takerFeeReceiver: bob.address }, orderSigner: owner, dataFormFixture, + minReturn: ether('0.1'), additionalDataForSettlement: fillOrderToData1, - needAddResolvers: true, + isMakingAmount: false, + fillingAmount: ether('100'), + feeType: 2, + integrator: bob.address, + resolverFee: 1000000, }); - const wethFeeAmount = ether('0.001'); - const daiFeeAmount = ether('1'); + const wethFeeAmount = ether('0.0001'); + const daiFeeAmount = ether('0.1'); // send fee amounts to resolver contract await weth.transfer(resolver.address, wethFeeAmount.toString()); await dai.connect(alice).transfer(resolver.address, daiFeeAmount.toString()); + // approve fee amounts to be spent by SettlementExtension + await resolver.approve(weth.address, settlement.address); + await resolver.approve(dai.address, settlement.address); const txn = await resolver.settleOrders(fillOrderToData0); - await expect(txn).to.changeTokenBalances(dai, [owner, alice, bob], [ether('-100'), ether('100'), ether('1')]); - await expect(txn).to.changeTokenBalances(weth, [owner, alice, bob], [ether('0.1'), ether('-0.1'), ether('0.001')]); + await expect(txn).to.changeTokenBalances(dai, [owner, alice, bob], [ether('100'), ether('-100'), ether('0.1')]); + await expect(txn).to.changeTokenBalances(weth, [owner, alice, bob], [ether('-0.11'), ether('0.1'), ether('0.0001')]); }); it('unidirectional recursive swap', async function () { From 9986097804283e26d578a582dfc0c89570ea16ad Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 25 Oct 2023 21:36:26 +0400 Subject: [PATCH 14/32] Fix Settlement tests except auction point tests --- contracts/SettlementExtension.sol | 1 + test/Settlement.js | 182 ++++++++++++++++++------------ 2 files changed, 108 insertions(+), 75 deletions(-) diff --git a/contracts/SettlementExtension.sol b/contracts/SettlementExtension.sol index e08ac8b4..a5499198 100644 --- a/contracts/SettlementExtension.sol +++ b/contracts/SettlementExtension.sol @@ -101,6 +101,7 @@ contract SettlementExtension is IPostInteraction, IAmountGetter, FeeBankCharger } currentRateBump = nextRateBump; currentPointTime = nextPointTime; + // auctionDetails = auctionDetails[5:]; } return (auctionFinishTime - block.timestamp) * currentRateBump / (auctionFinishTime - currentPointTime); diff --git a/test/Settlement.js b/test/Settlement.js index c60c87db..a68c8553 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -60,25 +60,33 @@ describe('Settlement', function () { additionalDataForSettlement = '', isInnermostOrder = false, isMakingAmount = true, - fillingAmount = orderData.makingAmount, + fillingAmount = isMakingAmount ? orderData.makingAmount : orderData.takingAmount, feeType = 0, integrator = orderSigner.address, resolverFee = 0, + auctionDetails = dataFormFixture.others.auctionDetails, }) { const { contracts: { lopv4, settlement, resolver }, - others: { chainId, auctionStartTime, auctionDetails }, + others: { chainId, auctionStartTime }, } = dataFormFixture; + let postInteractionFeeDataTypes = ['uint8']; + let postInteractionFeeData = [0]; + if (feeType === 1) { + postInteractionFeeDataTypes = [...postInteractionFeeDataTypes, 'bytes4']; + postInteractionFeeData = [feeType, '0x' + resolverFee.toString(16).padStart(8, '0')]; + } + if (feeType === 2) { + postInteractionFeeDataTypes = [...postInteractionFeeDataTypes, 'bytes20', 'bytes4']; + postInteractionFeeData = [feeType, integrator, '0x' + resolverFee.toString(16).padStart(8, '0')]; + } + const order = buildOrder(orderData, { makingAmountData: settlement.address + trim0x(auctionDetails), takingAmountData: settlement.address + trim0x(auctionDetails), postInteraction: settlement.address + - ( - feeType == 2 - ? trim0x(ethers.utils.solidityPack(['uint8', 'bytes20', 'bytes4'], [feeType, integrator, '0x' + resolverFee.toString(16).padStart(8, '0')])) - : trim0x(ethers.utils.solidityPack(['uint8', 'bytes4'], [feeType, '0x' + resolverFee.toString(16).padStart(8, '0')])) - ) + + trim0x(ethers.utils.solidityPack(postInteractionFeeDataTypes, postInteractionFeeData)) + trim0x(ethers.utils.solidityPack(['uint32', 'bytes10', 'uint16'], [auctionStartTime, '0x' + resolver.address.substring(22), 0])), }); @@ -87,7 +95,7 @@ describe('Settlement', function () { await resolver.approve(order.takerAsset, lopv4.address); const takerTraits = buildTakerTraits({ - isMakingAmount, + makingAmount: isMakingAmount, minReturn, extension: order.extension, interaction: resolver.address + (isInnermostOrder ? '01' : '00') + trim0x(additionalDataForSettlement), @@ -122,10 +130,9 @@ describe('Settlement', function () { }, orderSigner: alice, dataFormFixture, - minReturn: ether('90'), + minReturn: ether('100'), isInnermostOrder: true, isMakingAmount: false, - fillingAmount: ether('0.1'), }); const fillOrderToData0 = await buildCalldataForOrder({ @@ -139,10 +146,9 @@ describe('Settlement', function () { }, orderSigner: owner, dataFormFixture, - minReturn: ether('0.1'), + minReturn: ether('0.11'), additionalDataForSettlement: fillOrderToData1, isMakingAmount: false, - fillingAmount: ether('100'), }); const txn = await resolver.settleOrders(fillOrderToData0); @@ -169,10 +175,9 @@ describe('Settlement', function () { }, orderSigner: alice, dataFormFixture, - minReturn: ether('90'), + minReturn: ether('100'), isInnermostOrder: true, isMakingAmount: false, - fillingAmount: ether('0.1'), }); const fillOrderToData0 = await buildCalldataForOrder({ @@ -186,10 +191,9 @@ describe('Settlement', function () { }, orderSigner: owner, dataFormFixture, - minReturn: ether('0.1'), + minReturn: ether('0.11'), additionalDataForSettlement: fillOrderToData1, isMakingAmount: false, - fillingAmount: ether('100'), }); await weth.connect(alice).approve(lopv4.address, ether('0.11')); @@ -221,10 +225,9 @@ describe('Settlement', function () { }, orderSigner: alice, dataFormFixture, - minReturn: ether('90'), + minReturn: ether('100'), isInnermostOrder: true, isMakingAmount: false, - fillingAmount: ether('0.1'), }); const fillOrderToData0 = await buildCalldataForOrder({ @@ -238,10 +241,9 @@ describe('Settlement', function () { }, orderSigner: owner, dataFormFixture, - minReturn: ether('0.1'), + minReturn: ether('0.11'), additionalDataForSettlement: fillOrderToData1, isMakingAmount: false, - fillingAmount: ether('100'), }); const permit2 = await permit2Contract(); @@ -261,7 +263,7 @@ describe('Settlement', function () { it('opposite direction recursive swap with taking fee', async function () { const dataFormFixture = await loadFixture(initContracts); const { - contracts: { dai, weth, resolver, settlement }, + contracts: { dai, weth, settlement, resolver }, accounts: { owner, alice, bob }, } = dataFormFixture; @@ -276,10 +278,9 @@ describe('Settlement', function () { }, orderSigner: alice, dataFormFixture, - minReturn: ether('90'), + minReturn: ether('100'), isInnermostOrder: true, isMakingAmount: false, - fillingAmount: ether('0.1'), feeType: 2, integrator: bob.address, resolverFee: 1000000, @@ -296,10 +297,9 @@ describe('Settlement', function () { }, orderSigner: owner, dataFormFixture, - minReturn: ether('0.1'), + minReturn: ether('0.11'), additionalDataForSettlement: fillOrderToData1, isMakingAmount: false, - fillingAmount: ether('100'), feeType: 2, integrator: bob.address, resolverFee: 1000000, @@ -348,13 +348,14 @@ describe('Settlement', function () { takerAsset: weth.address, makingAmount: ether('15'), takingAmount: ether('0.015'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address] }, orderSigner: alice, dataFormFixture, + minReturn: ether('15'), additionalDataForSettlement: resolverArgs, isInnermostOrder: true, + isMakingAmount: false, }); const fillOrderToData0 = await buildCalldataForOrder({ @@ -364,13 +365,13 @@ describe('Settlement', function () { takerAsset: weth.address, makingAmount: ether('10'), takingAmount: ether('0.01'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address] }, orderSigner: alice, dataFormFixture, + minReturn: ether('10'), additionalDataForSettlement: fillOrderToData1, - needAddResolvers: true, + isMakingAmount: false, }); await weth.approve(resolver.address, ether('0.025')); @@ -394,12 +395,13 @@ describe('Settlement', function () { takerAsset: dai.address, makingAmount: ether('0.025'), takingAmount: ether('25'), - allowedSender: settlement.address, + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address] }, orderSigner: owner, dataFormFixture, + minReturn: ether('0.025'), isInnermostOrder: true, + isMakingAmount: false, }); const fillOrderToData1 = await buildCalldataForOrder({ @@ -409,12 +411,13 @@ describe('Settlement', function () { takerAsset: weth.address, makingAmount: ether('15'), takingAmount: ether('0.015'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address] }, orderSigner: alice, dataFormFixture, + minReturn: ether('15'), additionalDataForSettlement: fillOrderToData2, + isMakingAmount: false, }); const fillOrderToData0 = await buildCalldataForOrder({ @@ -424,13 +427,13 @@ describe('Settlement', function () { takerAsset: weth.address, makingAmount: ether('10'), takingAmount: ether('0.01'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address] }, orderSigner: alice, dataFormFixture, + minReturn: ether('10'), additionalDataForSettlement: fillOrderToData1, - needAddResolvers: true, + isMakingAmount: false, }); const txn = await resolver.settleOrders(fillOrderToData0); @@ -449,7 +452,7 @@ describe('Settlement', function () { dataFormFixture, }) => { const { - contracts: { dai, weth, settlement, resolver }, + contracts: { dai, weth, resolver }, accounts: { owner, alice }, others: { abiCoder }, } = dataFormFixture; @@ -484,6 +487,13 @@ describe('Settlement', function () { ], ); + let auctionDetails = ethers.utils.solidityPack( + ['uint32', 'uint24', 'uint24'], [startTime + auctionDelay, time.duration.hours(1), initialRateBump], + ); + for (let i = 0; i < points.length; i++) { + auctionDetails += trim0x(ethers.utils.solidityPack(['uint24', 'uint16'], [points[i][0], points[i][1]])); + } + const fillOrderToData = await buildCalldataForOrder({ orderData: { maker: alice.address, @@ -491,14 +501,16 @@ describe('Settlement', function () { takerAsset: weth.address, makingAmount: ether('100'), takingAmount: ether('0.1'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address], startTime, auctionDelay, auctionDuration, initialRateBump, points }, orderSigner: alice, dataFormFixture, + minReturn: ether('100'), additionalDataForSettlement: resolverCalldata, isInnermostOrder: true, - needAddResolvers: true, + isMakingAmount: false, + fillingAmount: actualTakingAmount, + auctionDetails, }); await weth.approve(resolver.address, actualTakingAmount); @@ -513,8 +525,8 @@ describe('Settlement', function () { } = dataFormFixture; const fillOrderToData = await prepareSingleOrder({ - startTime: await time.latest(), - auctionDelay: 60, + startTime: dataFormFixture.others.auctionStartTime, + auctionDelay: 60, // seconds dataFormFixture, }); @@ -523,7 +535,7 @@ describe('Settlement', function () { await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('-0.11'), ether('0.11')]); }); - describe('order with one bump point', async function () { + describe.skip('order with one bump point', async function () { it('matching order before bump point', async function () { const dataFormFixture = await loadFixture(initContracts); const { @@ -535,9 +547,9 @@ describe('Settlement', function () { const actualTakingAmount = ether('0.109'); const fillOrderToData = await prepareSingleOrder({ startTime, - initialRateBump: 1000000n, + initialRateBump: 10000n, auctionDuration: 1800, - points: [[240, 900000n]], + points: [[240, 9000]], targetTakingAmount: actualTakingAmount, dataFormFixture, }); @@ -593,7 +605,7 @@ describe('Settlement', function () { await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('-0.12'), ether('0.12')]); }); - it('set auctionDuration', async function () { + it.skip('set auctionDuration', async function () { const dataFormFixture = await loadFixture(initContracts); const { contracts: { dai, weth, resolver }, @@ -629,12 +641,15 @@ describe('Settlement', function () { takerAsset: dai.address, makingAmount: ether('0.1'), takingAmount: ether('100'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address], resolverFee: BACK_ORDER_FEE }, orderSigner: alice, dataFormFixture, + minReturn: ether('0.1'), isInnermostOrder: true, + isMakingAmount: false, + feeType: 1, + resolverFee: BACK_ORDER_FEE, }); const fillOrderToData0 = await buildCalldataForOrder({ @@ -644,13 +659,15 @@ describe('Settlement', function () { takerAsset: weth.address, makingAmount: ether('100'), takingAmount: ether('0.1'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address], resolverFee: ORDER_FEE }, orderSigner: owner, dataFormFixture, + minReturn: ether('100'), additionalDataForSettlement: fillOrderToData1, - needAddResolvers: true, + isMakingAmount: false, + feeType: 1, + resolverFee: ORDER_FEE, }); const availableCreditBefore = await settlement.availableCredit(resolver.address); @@ -692,15 +709,16 @@ describe('Settlement', function () { takerAsset: weth.address, makingAmount: ether('10'), takingAmount: ether('0.01'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address], resolverFee: ORDER_FEE }, orderSigner: alice, dataFormFixture, + minReturn: ether('0.01') * partialModifier / points, additionalDataForSettlement: resolverArgs, isInnermostOrder: true, - needAddResolvers: true, fillingAmount: ether('10') * partialModifier / points, + feeType: 1, + resolverFee: ORDER_FEE, }); await weth.approve(resolver.address, ether('0.01')); @@ -724,7 +742,7 @@ describe('Settlement', function () { const minimalPartialModifier = 1n; const points = ether('0.01'); - const minimalOrderFee = 1n; + const minimalOrderFee = 10n; const resolverArgs = abiCoder.encode( ['address[]', 'bytes[]'], @@ -747,15 +765,16 @@ describe('Settlement', function () { takerAsset: weth.address, makingAmount: ether('10'), takingAmount: ether('0.01'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address], resolverFee: minimalOrderFee }, orderSigner: alice, dataFormFixture, + minReturn: ether('0.01'), additionalDataForSettlement: resolverArgs, isInnermostOrder: true, - needAddResolvers: true, fillingAmount: ether('10') * minimalPartialModifier / points, + feeType: 1, + resolverFee: minimalOrderFee, }); await weth.approve(resolver.address, ether('0.01')); @@ -784,12 +803,14 @@ describe('Settlement', function () { takerAsset: dai.address, makingAmount: ether('0.1'), takingAmount: ether('100'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address], resolverFee: BACK_ORDER_FEE }, orderSigner: alice, dataFormFixture, + minReturn: ether('100'), isInnermostOrder: true, + feeType: 1, + resolverFee: BACK_ORDER_FEE, }); const fillOrderToData0 = await buildCalldataForOrder({ @@ -799,16 +820,23 @@ describe('Settlement', function () { takerAsset: weth.address, makingAmount: ether('100'), takingAmount: ether('0.1'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [resolver.address], resolverFee: '1000000' }, orderSigner: owner, dataFormFixture, + minReturn: ether('0.1'), additionalDataForSettlement: fillOrderToData1, - needAddResolvers: true, + feeType: 1, + resolverFee: '1000000', }); - await expect(resolver.settleOrders(fillOrderToData0)).to.be.revertedWithCustomError(settlement, 'NotEnoughCredit'); + try { + await resolver.settleOrders(fillOrderToData0); + expect.fail('should revert'); + } catch (e) { + expect(e.message).to.include('FailedExternalCall'); + expect(e.message).to.include('0xa7fd3792'); // NotEnoughCredit() + } }); describe('whitelist lock period', async function () { @@ -819,8 +847,7 @@ describe('Settlement', function () { accounts: { owner, alice }, } = dataFormFixture; - const currentTime = await time.latest(); - const threeHours = time.duration.hours('3'); + dataFormFixture.others.auctionStartTime += time.duration.hours('3'); const fillOrderToData1 = await buildCalldataForOrder({ orderData: { maker: alice.address, @@ -828,11 +855,11 @@ describe('Settlement', function () { takerAsset: dai.address, makingAmount: ether('0.1'), takingAmount: ether('100'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [alice.address, resolver.address], auctionDuration: threeHours * 2, resolverFee: ORDER_FEE }, orderSigner: alice, dataFormFixture, + minReturn: ether('100'), isInnermostOrder: true, }); @@ -843,23 +870,28 @@ describe('Settlement', function () { takerAsset: weth.address, makingAmount: ether('100'), takingAmount: ether('0.1'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), + makerTraits: buildMakerTraits(), }, - singleFusionData: { resolvers: [alice.address, resolver.address], auctionDuration: threeHours * 2, resolverFee: ORDER_FEE }, orderSigner: owner, dataFormFixture, + minReturn: ether('0.1'), additionalDataForSettlement: fillOrderToData1, - needAddResolvers: true, }); - await expect(resolver.settleOrders(fillOrderToData0)).to.be.revertedWithCustomError(settlement, 'ResolverIsNotWhitelisted'); + try { + await resolver.settleOrders(fillOrderToData0); + expect.fail('should revert'); + } catch (e) { + expect(e.message).to.include('FailedExternalCall'); + expect(e.message).to.include('0xfac829a0'); // ResolverIsNotWhitelisted() + } - await timeIncreaseTo(currentTime + threeHours + 1); + await timeIncreaseTo(dataFormFixture.others.auctionStartTime + 1); await resolver.settleOrders(fillOrderToData0); }); - it('should change by non-whitelisted resolver after publicCutOff', async function () { + it.skip('should change by non-whitelisted resolver after publicCutOff', async function () { const dataFormFixture = await loadFixture(initContracts); const { contracts: { dai, weth, settlement, resolver }, From 78e2106b081a03e9f4c5b7b3bc40df340e297457 Mon Sep 17 00:00:00 2001 From: Denis Date: Wed, 25 Oct 2023 21:40:19 +0400 Subject: [PATCH 15/32] Fix linter --- test/Settlement.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/Settlement.js b/test/Settlement.js index a68c8553..3620256a 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -1,4 +1,4 @@ -const { time, expect, ether, trim0x, timeIncreaseTo, getPermit, getPermit2, compressPermit, permit2Contract, deployContract, constants } = require('@1inch/solidity-utils'); +const { time, expect, ether, trim0x, timeIncreaseTo, getPermit, getPermit2, compressPermit, permit2Contract, deployContract } = require('@1inch/solidity-utils'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { ethers } = require('hardhat'); const { deploySwapTokens, getChainId } = require('./helpers/fixtures'); @@ -322,7 +322,7 @@ describe('Settlement', function () { it('unidirectional recursive swap', async function () { const dataFormFixture = await loadFixture(initContracts); const { - contracts: { dai, weth, settlement, resolver }, + contracts: { dai, weth, resolver }, accounts: { owner, alice }, others: { abiCoder }, } = dataFormFixture; @@ -384,7 +384,7 @@ describe('Settlement', function () { it('triple recursive swap', async function () { const dataFormFixture = await loadFixture(initContracts); const { - contracts: { dai, weth, settlement, resolver }, + contracts: { dai, weth, resolver }, accounts: { owner, alice }, } = dataFormFixture; @@ -791,7 +791,7 @@ describe('Settlement', function () { it('should not change when availableCredit is not enough', async function () { const dataFormFixture = await loadFixture(initContracts); const { - contracts: { dai, weth, settlement, resolver }, + contracts: { dai, weth, resolver }, accounts: { owner, alice }, others: { BACK_ORDER_FEE }, } = dataFormFixture; @@ -843,7 +843,7 @@ describe('Settlement', function () { it('should change only after whitelistedCutOff', async function () { const dataFormFixture = await loadFixture(initContracts); const { - contracts: { dai, weth, settlement, resolver }, + contracts: { dai, weth, resolver }, accounts: { owner, alice }, } = dataFormFixture; From 60064841507930762f4e731ef5070a5dc90a0a0e Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 26 Oct 2023 00:16:59 +0400 Subject: [PATCH 16/32] Fix WhitelistChecker tests --- test/WhitelistChecker.js | 225 +++++++++++++++++++----------------- test/helpers/fusionUtils.js | 190 +++++++++--------------------- 2 files changed, 173 insertions(+), 242 deletions(-) diff --git a/test/WhitelistChecker.js b/test/WhitelistChecker.js index 3c64f128..1e74530f 100644 --- a/test/WhitelistChecker.js +++ b/test/WhitelistChecker.js @@ -1,16 +1,22 @@ const { ethers } = require('hardhat'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { signOrder, buildOrder, compactSignature, fillWithMakingAmount } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); -const { expect, ether, trim0x, deployContract } = require('@1inch/solidity-utils'); +const { loadFixture, time } = require('@nomicfoundation/hardhat-network-helpers'); +const { buildOrder, buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); +const { expect, ether, deployContract, constants } = require('@1inch/solidity-utils'); const { deploySwapTokens, getChainId } = require('./helpers/fixtures'); -const { buildFusions } = require('./helpers/fusionUtils'); +const { buildCalldataForOrder } = require('./helpers/fusionUtils'); -describe.skip('WhitelistChecker // TODO: Update this tests', function () { +describe('WhitelistChecker // TODO: Update this tests', function () { async function initContracts() { const [owner, alice] = await ethers.getSigners(); const chainId = await getChainId(); const { dai, weth, lopv4 } = await deploySwapTokens(); + const whitelistRegistrySimple = await deployContract('WhitelistRegistrySimple', []); + const settlement = await deployContract('SettlementExtension', [lopv4.address, weth.address]); + + const ResolverMock = await ethers.getContractFactory('ResolverMock'); + const resolver = await ResolverMock.deploy(settlement.address, lopv4.address); + await dai.mint(owner.address, ether('100')); await dai.mint(alice.address, ether('100')); await weth.deposit({ value: ether('1') }); @@ -21,141 +27,144 @@ describe.skip('WhitelistChecker // TODO: Update this tests', function () { await weth.approve(lopv4.address, ether('1')); await weth.connect(alice).approve(lopv4.address, ether('1')); - const whitelistRegistrySimple = await deployContract('WhitelistRegistrySimple', []); - const settlement = await deployContract('SettlementExtension', [lopv4.address, weth.address]); + await resolver.approve(dai.address, lopv4.address); + await resolver.approve(weth.address, lopv4.address); - const ResolverMock = await ethers.getContractFactory('ResolverMock'); - const resolver = await ResolverMock.deploy(settlement.address, lopv4.address); + const auctionStartTime = await time.latest(); + const auctionDetails = ethers.utils.solidityPack( + ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], + ); return { contracts: { dai, weth, lopv4, whitelistRegistrySimple, settlement, resolver }, accounts: { owner, alice }, - others: { chainId }, + others: { chainId, auctionDetails, auctionStartTime }, }; } describe('should not work with non-whitelisted address', function () { - it('whitelist check in settleOrders method', async function () { - const { contracts: { dai, weth, lopv4, settlement }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContracts); - - const { fusions: [fusionDetails], hashes: [fusionHash], resolvers } = await buildFusions([{}]); - - const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('10'), - takingAmount: ether('0.01'), - maker: alice.address, + it('whitelist check in postInteraction method', async function () { + const dataFormFixture = await loadFixture(initContracts); + const { + contracts: { dai, weth, resolver }, + accounts: { alice }, + } = dataFormFixture; + + weth.transfer(resolver.address, ether('0.1')); + + const fillOrderToData = await buildCalldataForOrder({ + orderData: { + maker: alice.address, + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), + }, + orderSigner: alice, + dataFormFixture, + minReturn: ether('0.1'), + isInnermostOrder: true, + whitelistData: '0x' + constants.ZERO_ADDRESS.substring(22), }); - order.salt = fusionHash; - - const { r, vs } = compactSignature(await signOrder(order, chainId, lopv4.address, alice)); - const fillOrderToData = lopv4.interface.encodeFunctionData('fillOrderTo', [ - order, - r, - vs, - ether('10'), - fillWithMakingAmount('0'), - owner.address, - settlement.address + '01' + trim0x(fusionDetails), - ]) + trim0x(resolvers); - - await expect(settlement.settleOrders(fillOrderToData)) - .to.be.revertedWithCustomError(settlement, 'ResolverIsNotWhitelisted'); - }); - it('onlyThis modifier in takerInteraction method', async function () { - const { contracts: { dai, weth, lopv4, settlement }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContracts); + try { + await resolver.settleOrders(fillOrderToData); + expect.fail('should revert'); + } catch (e) { + expect(e.message).to.include('FailedExternalCall'); + expect(e.message).to.include('0x4b576069'); // ResolverIsNotWhitelisted() + } + }); - const order = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), - maker: alice.address, + it('only resolver can use takerInteraction method', async function () { + const dataFormFixture = await loadFixture(initContracts); + const { + contracts: { dai, weth, resolver, settlement, lopv4 }, + accounts: { alice }, + } = dataFormFixture; + + // Deploy another resolver + const ResolverMock = await ethers.getContractFactory('ResolverMock'); + const fakeResolver = await ResolverMock.deploy(settlement.address, lopv4.address); + + const fillOrderToData = await buildCalldataForOrder({ + orderData: { + maker: alice.address, + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), + }, + orderSigner: alice, + dataFormFixture, + minReturn: ether('0.1'), + isInnermostOrder: true, }); - const { r, vs } = compactSignature(await signOrder(order, chainId, lopv4.address, alice)); - await expect(lopv4.fillOrderTo(order, r, vs, ether('10'), fillWithMakingAmount('0'), owner.address, settlement.address + '01')) - .to.be.revertedWithCustomError(settlement, 'AccessDenied'); + // Change resolver to fakeResolver in takerInteraction + const fakeFillOrderToData = fillOrderToData.slice(0, fillOrderToData.length - 86) + fakeResolver.address.substring(2) + fillOrderToData.slice(-46); + + try { + await resolver.settleOrders(fakeFillOrderToData); + expect.fail('should revert'); + } catch (e) { + expect(e.message).to.include('FailedExternalCall'); + expect(e.message).to.include('0x5211a079'); // NotTaker() + } }); - it('onlyLimitOrderProtocol modifier', async function () { - const { contracts: { dai, weth, lopv4, settlement }, accounts: { owner, alice } } = await loadFixture(initContracts); + it('only LOP can use takerInteraction method', async function () { + const dataFormFixture = await loadFixture(initContracts); + const { + contracts: { dai, weth, resolver, lopv4 }, + accounts: { alice }, + } = dataFormFixture; const order = buildOrder({ + maker: alice.address, makerAsset: dai.address, takerAsset: weth.address, makingAmount: ether('100'), takingAmount: ether('0.1'), - maker: alice.address, }); const orderHash = await lopv4.hashOrder(order); - await expect(settlement.takerInteraction(order, orderHash, owner.address, '1', '1', '0', '0x')) - .to.be.revertedWithCustomError(settlement, 'AccessDenied'); + await expect(resolver.takerInteraction(order, '0x', orderHash, alice.address, '0', '0', '0', '0x')) + .to.be.revertedWithCustomError(resolver, 'OnlyLOP'); }); }); describe('should work with whitelisted address', function () { - async function initContractsAndSetStatus() { - const data = await initContracts(); - const { contracts: { whitelistRegistrySimple }, accounts: { owner } } = data; - await whitelistRegistrySimple.setStatus(owner.address, true); - return data; - } - it('whitelist check in settleOrders method', async function () { - const { contracts: { dai, weth, lopv4, settlement, resolver }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContractsAndSetStatus); - - const { fusions: [fusionDetails0, fusionDetails1], hashes: [fusionHash0, fusionHash1], resolvers } = await buildFusions([ - { resolvers: [resolver.address] }, - { resolvers: [resolver.address] }, - ]); - - const order0 = buildOrder({ - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), - maker: owner.address, + const dataFormFixture = await loadFixture(initContracts); + const { + contracts: { dai, weth, resolver }, + accounts: { alice }, + } = dataFormFixture; + + weth.transfer(resolver.address, ether('0.1')); + + const fillOrderToData = await buildCalldataForOrder({ + orderData: { + maker: alice.address, + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), + }, + orderSigner: alice, + dataFormFixture, + minReturn: ether('0.1'), + isInnermostOrder: true, + whitelistData: '0x' + resolver.address.substring(22), }); - order0.salt = fusionHash0; - const order1 = buildOrder({ - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.1'), - takingAmount: ether('100'), - maker: alice.address, - }); - order1.salt = fusionHash1; - - const { r: r1, vs: vs1 } = compactSignature(await signOrder(order1, chainId, lopv4.address, alice)); - const fillOrderToData1 = lopv4.interface.encodeFunctionData('fillOrderTo', [ - order1, - r1, - vs1, - ether('0.1'), - fillWithMakingAmount('0'), - resolver.address, - settlement.address + '01' + trim0x(fusionDetails1), - ]); - - const { r: r0, vs: vs0 } = compactSignature(await signOrder(order0, chainId, lopv4.address, owner)); - const fillOrderToData0 = lopv4.interface.encodeFunctionData('fillOrderTo', [ - order0, - r0, - vs0, - ether('100'), - fillWithMakingAmount('0'), - resolver.address, - settlement.address + '00' + trim0x(fusionDetails0) + trim0x(fillOrderToData1), - ]) + trim0x(resolvers); - - const txn = await resolver.settleOrders(fillOrderToData0); - await expect(txn).to.changeTokenBalances(dai, [owner, alice], [ether('-100'), ether('100')]); - await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('0.1'), ether('-0.1')]); + const txn = await resolver.settleOrders(fillOrderToData); + await expect(txn).to.changeTokenBalances(dai, [alice, resolver], [ether('-100'), ether('100')]); + await expect(txn).to.changeTokenBalances(weth, [alice, resolver], [ether('0.1'), ether('-0.1')]); }); }); }); diff --git a/test/helpers/fusionUtils.js b/test/helpers/fusionUtils.js index 3347e9e3..5f3aa077 100644 --- a/test/helpers/fusionUtils.js +++ b/test/helpers/fusionUtils.js @@ -1,146 +1,68 @@ -const { time, trim0x } = require('@1inch/solidity-utils'); -const { assert } = require('chai'); -const { keccak256 } = require('ethers/lib/utils'); +const { trim0x } = require('@1inch/solidity-utils'); +const { ethers } = require('hardhat'); +const { buildOrder, signOrder, buildTakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); -async function buildFusions(params) { - const allResolvers = [...new Set(params.flatMap((param) => param.resolvers).filter(item => item !== undefined))]; - const currentTime = await time.latest(); - const fusions = []; +async function buildCalldataForOrder({ + orderData, + orderSigner, + minReturn, + dataFormFixture, + additionalDataForSettlement = '', + isInnermostOrder = false, + isMakingAmount = true, + fillingAmount = isMakingAmount ? orderData.makingAmount : orderData.takingAmount, + feeType = 0, + integrator = orderSigner.address, + resolverFee = 0, + auctionDetails = dataFormFixture.others.auctionDetails, + whitelistData = '0x' + dataFormFixture.contracts.resolver.address.substring(22), +}) { + const { + contracts: { lopv4, settlement, resolver }, + others: { chainId, auctionStartTime }, + } = dataFormFixture; - for (let { - resolvers = [], - points = [], - startTime, - auctionDelay = 0n, - auctionDuration = time.duration.hours(1), - initialRateBump = 0n, - resolverFee = 0n, - publicTimeDelay, - takerFee = 0n, - takerFeeReceiver = undefined, - } of params) { - if (!startTime) { - startTime = currentTime; - } - - if (!publicTimeDelay) { - publicTimeDelay = auctionDuration >> 1; - } - - // Order `interaction` prefix structure: - // struct Data { - // bytes1 flags; - // bytes4 startTime; - // bytes2 auctionDelay; - // bytes3 auctionDuration; - // bytes3 initialRateBump; - // bytes4 resolverFee; - // bytes2 publicTimeDelay; - // (bytes2,bytes10)[N] resolversAndTimeDeltas; - // (bytes2,bytes3)[M] pointsAndTimeDeltas; - // bytes24? takingFee; // optional if flags has _HAS_TAKING_FEE_FLAG - // } - assert(resolvers.length <= 15, 'Too many resolvers'); - assert(points.length <= 7, 'Too many points'); - assert(BigInt(startTime) < (1n << 32n), 'Auction start is too big'); - assert(BigInt(auctionDelay) < (1n << 16n), 'Auction delay is too big'); - assert(BigInt(auctionDuration) < (1n << 24n), 'Auction duration is too big'); - assert(BigInt(initialRateBump) < (1n << 24n), 'Initial rate bump is too big'); - assert(BigInt(resolverFee) < (1n << 32n), 'Resolver fee is too big'); - assert(BigInt(publicTimeDelay) < (1n << 16n), 'Public time delay is too big'); - - const flags = (takerFee > 0 ? 0x80 : 0) | (resolvers.length << 3) | points.length; - - fusions.push( - '0x' + flags.toString(16).padStart(2, '0') + - startTime.toString(16).padStart(8, '0') + - auctionDelay.toString(16).padStart(4, '0') + - auctionDuration.toString(16).padStart(6, '0') + - initialRateBump.toString(16).padStart(6, '0') + - resolverFee.toString(16).padStart(8, '0') + - publicTimeDelay.toString(16).padStart(4, '0') + - resolvers.map((resolver, i) => { - const delta = i === 0 ? 0 : auctionDuration / resolvers.length; - assert(BigInt(delta) < (1n << 16n), 'Resolver time delta is too big'); - return allResolvers.indexOf(resolver).toString(16).padStart(2, '0') + delta.toString(16).padStart(4, '0'); - }).join('') + - points.map(([delta, bump]) => { - assert(BigInt(delta) < (1n << 16n), 'Point time delta is too big'); - return bump.toString(16).padStart(6, '0') + delta.toString(16).padStart(4, '0'); - }).join('') + - (takerFee > 0 ? takerFee.toString(16).padStart(8, '0') + trim0x(takerFeeReceiver) : ''), - ); + let postInteractionFeeDataTypes = ['uint8']; + let postInteractionFeeData = [0]; + if (feeType === 1) { + postInteractionFeeDataTypes = [...postInteractionFeeDataTypes, 'bytes4']; + postInteractionFeeData = [feeType, '0x' + resolverFee.toString(16).padStart(8, '0')]; + } + if (feeType === 2) { + postInteractionFeeDataTypes = [...postInteractionFeeDataTypes, 'bytes20', 'bytes4']; + postInteractionFeeData = [feeType, integrator, '0x' + resolverFee.toString(16).padStart(8, '0')]; } - return { - fusions, - hashes: (await Promise.all(params.map(buildFusion))).map(keccak256), - resolvers: '0x' + allResolvers.map((resolver) => resolver.substring(22)).join('') + allResolvers.length.toString(16).padStart(2, '0'), - }; -} + const order = buildOrder(orderData, { + makingAmountData: settlement.address + trim0x(auctionDetails), + takingAmountData: settlement.address + trim0x(auctionDetails), + postInteraction: settlement.address + + trim0x(ethers.utils.solidityPack(postInteractionFeeDataTypes, postInteractionFeeData)) + + trim0x(ethers.utils.solidityPack(['uint32', 'bytes10', 'uint16'], [auctionStartTime, whitelistData, 0])), + }); -async function buildFusion({ - resolvers = [], - points = [], - startTime, - auctionDelay = 0n, - auctionDuration = time.duration.hours(1), - initialRateBump = 0n, - resolverFee = 0n, - publicTimeDelay, - takerFee = 0n, - takerFeeReceiver = undefined, -} = {}) { - if (!startTime) { - startTime = await time.latest(); - } + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, lopv4.address, orderSigner)); - if (!publicTimeDelay) { - publicTimeDelay = auctionDuration >> 1; - } + await resolver.approve(order.takerAsset, lopv4.address); - // Order `interaction` prefix structure: - // struct Data { - // bytes1 flags; - // bytes4 startTime; - // bytes2 auctionDelay; - // bytes3 auctionDuration; - // bytes3 initialRateBump; - // bytes4 resolverFee; - // bytes2 publicTimeDelay; - // (bytes2,bytes10)[N] resolversAndTimeDeltas; - // (bytes2,bytes3)[M] pointsAndTimeDeltas; - // bytes24? takingFee; // optional if flags has _HAS_TAKING_FEE_FLAG - // } - assert(resolvers.length <= 15, 'Too many resolvers'); - assert(points.length <= 7, 'Too many points'); - assert(BigInt(startTime) < (1n << 32n), 'Auction start is too big'); - assert(BigInt(auctionDelay) < (1n << 16n), 'Auction delay is too big'); - assert(BigInt(auctionDuration) < (1n << 24n), 'Auction duration is too big'); - assert(BigInt(initialRateBump) < (1n << 24n), 'Initial rate bump is too big'); - assert(BigInt(resolverFee) < (1n << 32n), 'Resolver fee is too big'); - assert(BigInt(publicTimeDelay) < (1n << 16n), 'Public time delay is too big'); + const takerTraits = buildTakerTraits({ + makingAmount: isMakingAmount, + minReturn, + extension: order.extension, + interaction: resolver.address + (isInnermostOrder ? '01' : '00') + trim0x(additionalDataForSettlement), + target: resolver.address, + }); - const flags = (takerFee > 0 ? 0x80 : 0) | (resolvers.length << 3) | points.length; - return '0x' + flags.toString(16).padStart(2, '0') + - startTime.toString(16).padStart(8, '0') + - auctionDelay.toString(16).padStart(4, '0') + - auctionDuration.toString(16).padStart(6, '0') + - initialRateBump.toString(16).padStart(6, '0') + - resolverFee.toString(16).padStart(8, '0') + - publicTimeDelay.toString(16).padStart(4, '0') + - resolvers.map((resolver, i) => { - const delta = i === 0 ? 0 : auctionDuration / resolvers.length; - assert(BigInt(delta) < (1n << 16n), 'Resolver time delta is too big'); - return resolver.substring(22) + delta.toString(16).padStart(4, '0'); - }).join('') + - points.map(([delta, bump]) => { - assert(BigInt(delta) < (1n << 16n), 'Point time delta is too big'); - return bump.toString(16).padStart(6, '0') + delta.toString(16).padStart(4, '0'); - }).join('') + - (takerFee > 0 ? takerFee.toString(16).padStart(8, '0') + trim0x(takerFeeReceiver) : ''); + return lopv4.interface.encodeFunctionData('fillOrderArgs', [ + order, + r, + vs, + fillingAmount, + takerTraits.traits, + takerTraits.args, + ]); } module.exports = { - buildFusions, + buildCalldataForOrder, }; From d04091496a16cff3171a1d5773da75a5163ef7c1 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 26 Oct 2023 00:32:34 +0400 Subject: [PATCH 17/32] Refactor tests --- test/Settlement.js | 146 ++++++--------------------------------- test/WhitelistChecker.js | 50 ++------------ test/helpers/fixtures.js | 48 ++++++++++++- 3 files changed, 74 insertions(+), 170 deletions(-) diff --git a/test/Settlement.js b/test/Settlement.js index 3620256a..969857f7 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -1,119 +1,17 @@ -const { time, expect, ether, trim0x, timeIncreaseTo, getPermit, getPermit2, compressPermit, permit2Contract, deployContract } = require('@1inch/solidity-utils'); -const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { ethers } = require('hardhat'); -const { deploySwapTokens, getChainId } = require('./helpers/fixtures'); -const { buildOrder, signOrder, buildTakerTraits, buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { time, expect, ether, trim0x, timeIncreaseTo, getPermit, getPermit2, compressPermit, permit2Contract } = require('@1inch/solidity-utils'); +const { buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); +const { initContractsForSettlement } = require('./helpers/fixtures'); +const { buildCalldataForOrder } = require('./helpers/fusionUtils'); const ORDER_FEE = 100n; const BACK_ORDER_FEE = 125n; const BASE_POINTS = ether('0.001'); // 1e15 describe('Settlement', function () { - async function initContracts() { - const abiCoder = ethers.utils.defaultAbiCoder; - const chainId = await getChainId(); - const [owner, alice, bob] = await ethers.getSigners(); - - const { dai, weth, inch, lopv4 } = await deploySwapTokens(); - - await dai.transfer(alice.address, ether('101')); - await inch.mint(owner.address, ether('100')); - await weth.deposit({ value: ether('1') }); - await weth.connect(alice).deposit({ value: ether('1') }); - - const settlement = await deployContract('SettlementExtensionMock', [lopv4.address, inch.address]); - - const FeeBank = await ethers.getContractFactory('FeeBank'); - const feeBank = FeeBank.attach(await settlement.feeBank()); - - const ResolverMock = await ethers.getContractFactory('ResolverMock'); - const resolver = await ResolverMock.deploy(settlement.address, lopv4.address); - - await inch.approve(feeBank.address, ether('100')); - await feeBank.depositFor(resolver.address, ether('100')); - - await dai.approve(lopv4.address, ether('100')); - await dai.connect(alice).approve(lopv4.address, ether('100')); - await weth.approve(lopv4.address, ether('1')); - await weth.connect(alice).approve(lopv4.address, ether('1')); - - await resolver.approve(dai.address, lopv4.address); - await resolver.approve(weth.address, lopv4.address); - - const auctionStartTime = await time.latest(); - const auctionDetails = ethers.utils.solidityPack( - ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], - ); - - return { - contracts: { dai, weth, lopv4, settlement, feeBank, resolver }, - accounts: { owner, alice, bob }, - others: { chainId, abiCoder, auctionStartTime, auctionDetails }, - }; - } - - async function buildCalldataForOrder({ - orderData, - orderSigner, - minReturn, - dataFormFixture, - additionalDataForSettlement = '', - isInnermostOrder = false, - isMakingAmount = true, - fillingAmount = isMakingAmount ? orderData.makingAmount : orderData.takingAmount, - feeType = 0, - integrator = orderSigner.address, - resolverFee = 0, - auctionDetails = dataFormFixture.others.auctionDetails, - }) { - const { - contracts: { lopv4, settlement, resolver }, - others: { chainId, auctionStartTime }, - } = dataFormFixture; - - let postInteractionFeeDataTypes = ['uint8']; - let postInteractionFeeData = [0]; - if (feeType === 1) { - postInteractionFeeDataTypes = [...postInteractionFeeDataTypes, 'bytes4']; - postInteractionFeeData = [feeType, '0x' + resolverFee.toString(16).padStart(8, '0')]; - } - if (feeType === 2) { - postInteractionFeeDataTypes = [...postInteractionFeeDataTypes, 'bytes20', 'bytes4']; - postInteractionFeeData = [feeType, integrator, '0x' + resolverFee.toString(16).padStart(8, '0')]; - } - - const order = buildOrder(orderData, { - makingAmountData: settlement.address + trim0x(auctionDetails), - takingAmountData: settlement.address + trim0x(auctionDetails), - postInteraction: settlement.address + - trim0x(ethers.utils.solidityPack(postInteractionFeeDataTypes, postInteractionFeeData)) + - trim0x(ethers.utils.solidityPack(['uint32', 'bytes10', 'uint16'], [auctionStartTime, '0x' + resolver.address.substring(22), 0])), - }); - - const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, lopv4.address, orderSigner)); - - await resolver.approve(order.takerAsset, lopv4.address); - - const takerTraits = buildTakerTraits({ - makingAmount: isMakingAmount, - minReturn, - extension: order.extension, - interaction: resolver.address + (isInnermostOrder ? '01' : '00') + trim0x(additionalDataForSettlement), - target: resolver.address, - }); - - return lopv4.interface.encodeFunctionData('fillOrderArgs', [ - order, - r, - vs, - fillingAmount, - takerTraits.traits, - takerTraits.args, - ]); - } - it('opposite direction recursive swap', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, @@ -157,7 +55,7 @@ describe('Settlement', function () { }); it('settle orders with permits, permit', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, lopv4, resolver }, accounts: { owner, alice }, @@ -207,7 +105,7 @@ describe('Settlement', function () { }); it('settle orders with permits, permit2', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, lopv4, resolver }, accounts: { owner, alice }, @@ -261,7 +159,7 @@ describe('Settlement', function () { }); it('opposite direction recursive swap with taking fee', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, settlement, resolver }, accounts: { owner, alice, bob }, @@ -320,7 +218,7 @@ describe('Settlement', function () { }); it('unidirectional recursive swap', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, @@ -382,7 +280,7 @@ describe('Settlement', function () { }); it('triple recursive swap', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, @@ -518,7 +416,7 @@ describe('Settlement', function () { }; it('matching order before orderTime has maximal rate bump', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, @@ -537,7 +435,7 @@ describe('Settlement', function () { describe.skip('order with one bump point', async function () { it('matching order before bump point', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, @@ -562,7 +460,7 @@ describe('Settlement', function () { }); it('matching order after bump point', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, @@ -587,7 +485,7 @@ describe('Settlement', function () { }); it('set initial rate', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, @@ -606,7 +504,7 @@ describe('Settlement', function () { }); it.skip('set auctionDuration', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, @@ -628,7 +526,7 @@ describe('Settlement', function () { }); it('should change availableCredit with non-zero fee', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, settlement, resolver }, accounts: { owner, alice }, @@ -678,7 +576,7 @@ describe('Settlement', function () { }); it('partial fill with taking fee', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, settlement, resolver }, accounts: { owner, alice }, @@ -733,7 +631,7 @@ describe('Settlement', function () { }); it('resolver should pay minimal 1 wei fee', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, settlement, resolver }, accounts: { owner, alice }, @@ -789,7 +687,7 @@ describe('Settlement', function () { }); it('should not change when availableCredit is not enough', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, @@ -841,7 +739,7 @@ describe('Settlement', function () { describe('whitelist lock period', async function () { it('should change only after whitelistedCutOff', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, @@ -892,7 +790,7 @@ describe('Settlement', function () { }); it.skip('should change by non-whitelisted resolver after publicCutOff', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, settlement, resolver }, accounts: { owner, alice }, diff --git a/test/WhitelistChecker.js b/test/WhitelistChecker.js index 1e74530f..4432d928 100644 --- a/test/WhitelistChecker.js +++ b/test/WhitelistChecker.js @@ -1,50 +1,14 @@ const { ethers } = require('hardhat'); -const { loadFixture, time } = require('@nomicfoundation/hardhat-network-helpers'); +const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); +const { expect, ether, constants } = require('@1inch/solidity-utils'); const { buildOrder, buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); -const { expect, ether, deployContract, constants } = require('@1inch/solidity-utils'); -const { deploySwapTokens, getChainId } = require('./helpers/fixtures'); +const { initContractsForSettlement } = require('./helpers/fixtures'); const { buildCalldataForOrder } = require('./helpers/fusionUtils'); describe('WhitelistChecker // TODO: Update this tests', function () { - async function initContracts() { - const [owner, alice] = await ethers.getSigners(); - const chainId = await getChainId(); - const { dai, weth, lopv4 } = await deploySwapTokens(); - - const whitelistRegistrySimple = await deployContract('WhitelistRegistrySimple', []); - const settlement = await deployContract('SettlementExtension', [lopv4.address, weth.address]); - - const ResolverMock = await ethers.getContractFactory('ResolverMock'); - const resolver = await ResolverMock.deploy(settlement.address, lopv4.address); - - await dai.mint(owner.address, ether('100')); - await dai.mint(alice.address, ether('100')); - await weth.deposit({ value: ether('1') }); - await weth.connect(alice).deposit({ value: ether('1') }); - - await dai.approve(lopv4.address, ether('100')); - await dai.connect(alice).approve(lopv4.address, ether('100')); - await weth.approve(lopv4.address, ether('1')); - await weth.connect(alice).approve(lopv4.address, ether('1')); - - await resolver.approve(dai.address, lopv4.address); - await resolver.approve(weth.address, lopv4.address); - - const auctionStartTime = await time.latest(); - const auctionDetails = ethers.utils.solidityPack( - ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], - ); - - return { - contracts: { dai, weth, lopv4, whitelistRegistrySimple, settlement, resolver }, - accounts: { owner, alice }, - others: { chainId, auctionDetails, auctionStartTime }, - }; - } - describe('should not work with non-whitelisted address', function () { it('whitelist check in postInteraction method', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { alice }, @@ -78,7 +42,7 @@ describe('WhitelistChecker // TODO: Update this tests', function () { }); it('only resolver can use takerInteraction method', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver, settlement, lopv4 }, accounts: { alice }, @@ -116,7 +80,7 @@ describe('WhitelistChecker // TODO: Update this tests', function () { }); it('only LOP can use takerInteraction method', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver, lopv4 }, accounts: { alice }, @@ -138,7 +102,7 @@ describe('WhitelistChecker // TODO: Update this tests', function () { describe('should work with whitelisted address', function () { it('whitelist check in settleOrders method', async function () { - const dataFormFixture = await loadFixture(initContracts); + const dataFormFixture = await loadFixture(initContractsForSettlement); const { contracts: { dai, weth, resolver }, accounts: { alice }, diff --git a/test/helpers/fixtures.js b/test/helpers/fixtures.js index 45360efc..230cc11d 100644 --- a/test/helpers/fixtures.js +++ b/test/helpers/fixtures.js @@ -1,7 +1,7 @@ const fs = require('fs'); const path = require('path'); const { ethers } = require('hardhat'); -const { ether, deployContract } = require('@1inch/solidity-utils'); +const { ether, deployContract, time } = require('@1inch/solidity-utils'); async function getChainId() { return (await ethers.provider.getNetwork()).chainId; @@ -15,14 +15,56 @@ async function deploySwapTokens() { const lopv4 = await deployContract('LimitOrderProtocol', [weth.address]); const LimitOrderProtocolV3 = JSON.parse(fs.readFileSync(path.join(__dirname, '../../artifacts-v1/LimitOrderProtocolV3.json'), 'utf8')); - // const lopv3 = await deployContract(LimitOrderProtocolV3.abi, [weth.address]); const ContractFactory = await ethers.getContractFactory(LimitOrderProtocolV3.abi, LimitOrderProtocolV3.bytecode); const lopv3 = await ContractFactory.deploy(weth.address); return { dai, weth, inch, lopv3, lopv4 }; } +async function initContractsForSettlement() { + const abiCoder = ethers.utils.defaultAbiCoder; + const chainId = await getChainId(); + const [owner, alice, bob] = await ethers.getSigners(); + + const { dai, weth, inch, lopv4 } = await deploySwapTokens(); + + await dai.transfer(alice.address, ether('101')); + await inch.mint(owner.address, ether('100')); + await weth.deposit({ value: ether('1') }); + await weth.connect(alice).deposit({ value: ether('1') }); + + const settlement = await deployContract('SettlementExtensionMock', [lopv4.address, inch.address]); + + const FeeBank = await ethers.getContractFactory('FeeBank'); + const feeBank = FeeBank.attach(await settlement.feeBank()); + + const ResolverMock = await ethers.getContractFactory('ResolverMock'); + const resolver = await ResolverMock.deploy(settlement.address, lopv4.address); + + await inch.approve(feeBank.address, ether('100')); + await feeBank.depositFor(resolver.address, ether('100')); + + await dai.approve(lopv4.address, ether('100')); + await dai.connect(alice).approve(lopv4.address, ether('100')); + await weth.approve(lopv4.address, ether('1')); + await weth.connect(alice).approve(lopv4.address, ether('1')); + + await resolver.approve(dai.address, lopv4.address); + await resolver.approve(weth.address, lopv4.address); + + const auctionStartTime = await time.latest(); + const auctionDetails = ethers.utils.solidityPack( + ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], + ); + + return { + contracts: { dai, weth, lopv4, settlement, feeBank, resolver }, + accounts: { owner, alice, bob }, + others: { chainId, abiCoder, auctionStartTime, auctionDetails }, + }; +} + module.exports = { - deployContract, + initContractsForSettlement, deploySwapTokens, getChainId, }; From ab9f152606d532944849359b30921b76a2ee6872 Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 26 Oct 2023 00:51:33 +0400 Subject: [PATCH 18/32] Add measure gas tests --- test/MeasureGas.js | 163 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 140 insertions(+), 23 deletions(-) diff --git a/test/MeasureGas.js b/test/MeasureGas.js index b6869491..7c69299d 100644 --- a/test/MeasureGas.js +++ b/test/MeasureGas.js @@ -3,8 +3,8 @@ const hre = require('hardhat'); const path = require('path'); const { ethers } = hre; const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); -const { time, expect, ether, trim0x } = require('@1inch/solidity-utils'); -const { deploySwapTokens, getChainId, deployContract } = require('./helpers/fixtures'); +const { time, expect, ether, trim0x, deployContract } = require('@1inch/solidity-utils'); +const { deploySwapTokens, getChainId } = require('./helpers/fixtures'); const { buildOrder, signOrder, buildTakerTraits, buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); const settlementV1Utils = require('@1inch/limit-order-settlement-v1/test/helpers/orderUtils'); @@ -32,20 +32,24 @@ describe('MeasureGas', function () { const ContractFactory = await ethers.getContractFactory(SettlementV1.abi, SettlementV1.bytecode); const settlement = await ContractFactory.deploy(lopv3.address, inch.address); - const resolvers = []; + const resolversV1 = []; const ResolverV1Mock = JSON.parse(fs.readFileSync(path.join(__dirname, '../artifacts-v1/ResolverV1Mock.json'), 'utf8')); for (let i = 0; i < RESOLVERS_NUMBER; i++) { - // resolvers[i] = await deployContract(ResolverV1Mock.abi, [settlement.address, lopv3.address]); const ResolverMockFactory = await ethers.getContractFactory(ResolverV1Mock.abi, ResolverV1Mock.bytecode); - resolvers[i] = await ResolverMockFactory.deploy(settlement.address); + resolversV1[i] = await ResolverMockFactory.deploy(settlement.address); } const FeeBank = await ethers.getContractFactory('FeeBank'); const feeBank = FeeBank.attach(await settlement.feeBank()); await inch.approve(feeBank.address, ether('100')); - await feeBank.depositFor(resolvers[0].address, ether('100')); + await feeBank.depositFor(resolversV1[0].address, ether('100')); + + const ResolverMock = await ethers.getContractFactory('ResolverMock'); + const resolver = await ResolverMock.deploy(settlement.address, lopv4.address); + await resolver.approve(dai.address, lopv4.address); + await resolver.approve(weth.address, lopv4.address); return { - contracts: { dai, weth, lopv3, lopv4, settlement, settlementExtension, feeBank, resolvers }, + contracts: { dai, weth, lopv3, lopv4, settlement, settlementExtension, feeBank, resolversV1, resolver }, accounts: { owner, alice }, others: { chainId, abiCoder }, }; @@ -65,7 +69,7 @@ describe('MeasureGas', function () { describe('SettlementV1', function () { it('1 fill for 1 order', async function () { - const { contracts: { dai, weth, lopv3, settlement, resolvers }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContractsAndApproves); + const { contracts: { dai, weth, lopv3, settlement, resolversV1 }, accounts: { owner, alice }, others: { chainId } } = await loadFixture(initContractsAndApproves); const makerAsset = dai.address; const takerAsset = weth.address; @@ -85,8 +89,8 @@ describe('MeasureGas', function () { from: alice.address, }, { - whitelistedAddrs: [owner.address, ...(resolvers.map(r => r.address))], - whitelistedCutOffs: [0, ...(resolvers.map(r => 0))], + whitelistedAddrs: [owner.address, ...(resolversV1.map(r => r.address))], + whitelistedCutOffs: [0, ...(resolversV1.map(r => 0))], publicCutOff: time.duration.minutes(30), }, ); @@ -95,10 +99,10 @@ describe('MeasureGas', function () { const interaction = settlement.address + '01' + - trim0x(resolvers[0].address) + + trim0x(resolversV1[0].address) + '0000000000000000000000000000000000000000000000000000000000000000' + ''; - await weth.transfer(resolvers[0].address, takingAmount); + await weth.transfer(resolversV1[0].address, takingAmount); const tx = await settlement.settleOrders( '0x' + lopv3.interface.encodeFunctionData('fillOrderTo', [ @@ -108,19 +112,19 @@ describe('MeasureGas', function () { makingAmount, 0, takingAmount, - resolvers[0].address, + resolversV1[0].address, ]).substring(10), ); console.log(`1 fill for 1 order gasUsed: ${(await tx.wait()).gasUsed}`); - await expect(tx).to.changeTokenBalances(dai, [resolvers[0], alice], [ether('100'), ether('-100')]); - await expect(tx).to.changeTokenBalances(weth, [resolvers[0], alice], [ether('-0.1'), ether('0.1')]); + await expect(tx).to.changeTokenBalances(dai, [resolversV1[0], alice], [ether('100'), ether('-100')]); + await expect(tx).to.changeTokenBalances(weth, [resolversV1[0], alice], [ether('-0.1'), ether('0.1')]); }); it('1 fill for 5 orders in a batch', async function () { - const { contracts: { dai, weth, lopv3, settlement, resolvers }, accounts: { alice, owner }, others: { chainId } } = await loadFixture(initContractsAndApproves); + const { contracts: { dai, weth, lopv3, settlement, resolversV1 }, accounts: { alice, owner }, others: { chainId } } = await loadFixture(initContractsAndApproves); - const resolverAddresses = resolvers.map(r => r.address); - const whitelistedCutOffsTmp = resolvers.map(r => 0); + const resolverAddresses = resolversV1.map(r => r.address); + const whitelistedCutOffsTmp = resolversV1.map(r => 0); // Build orders and compact signatures const orders = []; @@ -171,7 +175,7 @@ describe('MeasureGas', function () { // Encode data for fillingg orders const fillOrdersToData = []; - fillOrdersToData[5] = settlement.address + '01' + trim0x(resolvers[0].address) + '0000000000000000000000000000000000000000000000000000000000000000'; + fillOrdersToData[5] = settlement.address + '01' + trim0x(resolversV1[0].address) + '0000000000000000000000000000000000000000000000000000000000000000'; fillOrdersToData[4] = settlement.address + '00' + @@ -183,7 +187,7 @@ describe('MeasureGas', function () { ether('0.11'), 0, ether('10'), - resolvers[0].address, + resolversV1[0].address, ]) .substring(10); for (let i = 3; i >= 1; i--) { @@ -198,7 +202,7 @@ describe('MeasureGas', function () { ether((i + 1).toString()), 0, ether(((i + 1) / 100).toString()), - resolvers[0].address, + resolversV1[0].address, ]) .substring(10); } @@ -211,12 +215,12 @@ describe('MeasureGas', function () { ether('1'), 0, ether('0.01'), - resolvers[0].address, // settlement.address, + resolversV1[0].address, // settlement.address, ]).substring(10), ); console.log(`1 fill for 5 orders in a batch gasUsed: ${(await tx.wait()).gasUsed}`); await expect(tx).to.changeTokenBalances(weth, [owner, alice], [ether('-0.11'), ether('0.1')]); - await expect(tx).to.changeTokenBalances(dai, [owner, alice, resolvers[0]], [ether('1'), ether('-10'), ether('9')]); + await expect(tx).to.changeTokenBalances(dai, [owner, alice, resolversV1[0]], [ether('1'), ether('-10'), ether('9')]); }); }); @@ -266,5 +270,118 @@ describe('MeasureGas', function () { await expect(tx).to.changeTokenBalances(dai, [owner, alice], [ether('100'), ether('-100')]); await expect(tx).to.changeTokenBalances(weth, [owner, alice], [ether('-0.1'), ether('0.1')]); }); + + it('extension 1 fill for 1 order via resolver with funds', async function () { + const { contracts: { dai, weth, lopv4, settlementExtension, resolver }, accounts: { alice }, others: { chainId } } = await loadFixture(initContractsAndApproves); + + const auctionStartTime = await time.latest(); + const auctionDetails = ethers.utils.solidityPack( + ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], + ); + + const order = buildOrder({ + maker: alice.address, + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), + }, { + makingAmountData: settlementExtension.address + trim0x(auctionDetails), + takingAmountData: settlementExtension.address + trim0x(auctionDetails), + postInteraction: settlementExtension.address + trim0x(ethers.utils.solidityPack( + ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + resolver.address.substring(22), 0], + )), + }); + + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, lopv4.address, alice)); + + const takerTraits = buildTakerTraits({ + makingAmount: true, + minReturn: ether('100'), + extension: order.extension, + }); + + await weth.transfer(resolver.address, ether('0.1')); + await resolver.approve(weth.address, lopv4.address); + + const tx = await resolver.settleOrders( + lopv4.interface.encodeFunctionData('fillOrderArgs', [ + order, + r, + vs, + ether('100'), + takerTraits.traits, + takerTraits.args, + ]), + ); + console.log(`1 fill for 1 order via resolver with funds gasUsed: ${(await tx.wait()).gasUsed}`); + await expect(tx).to.changeTokenBalances(dai, [resolver, alice], [ether('100'), ether('-100')]); + await expect(tx).to.changeTokenBalances(weth, [resolver, alice], [ether('-0.1'), ether('0.1')]); + }); + + it('extension 1 fill for 1 order via resolver without funds', async function () { + const { contracts: { dai, weth, lopv4, settlementExtension, resolver }, accounts: { owner, alice }, others: { chainId, abiCoder } } = await loadFixture(initContractsAndApproves); + + const auctionStartTime = await time.latest(); + const auctionDetails = ethers.utils.solidityPack( + ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], + ); + + const resolverArgs = abiCoder.encode( + ['address[]', 'bytes[]'], + [ + [weth.address], + [ + weth.interface.encodeFunctionData('transferFrom', [ + owner.address, + resolver.address, + ether('0.1'), + ]), + ], + ], + ); + + const order = buildOrder({ + maker: alice.address, + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits(), + }, { + makingAmountData: settlementExtension.address + trim0x(auctionDetails), + takingAmountData: settlementExtension.address + trim0x(auctionDetails), + postInteraction: settlementExtension.address + trim0x(ethers.utils.solidityPack( + ['uint8', 'uint32', 'bytes10', 'uint16'], [0, auctionStartTime, '0x' + resolver.address.substring(22), 0], + )), + }); + + const { r, _vs: vs } = ethers.utils.splitSignature(await signOrder(order, chainId, lopv4.address, alice)); + + const takerTraits = buildTakerTraits({ + makingAmount: true, + minReturn: ether('100'), + extension: order.extension, + interaction: resolver.address + '01' + trim0x(resolverArgs), + }); + + await weth.approve(resolver.address, ether('0.1')); + await resolver.approve(weth.address, lopv4.address); + + const tx = await resolver.settleOrders( + lopv4.interface.encodeFunctionData('fillOrderArgs', [ + order, + r, + vs, + ether('100'), + takerTraits.traits, + takerTraits.args, + ]), + ); + console.log(`1 fill for 1 order via resolver without money gasUsed: ${(await tx.wait()).gasUsed}`); + await expect(tx).to.changeTokenBalances(dai, [resolver, alice], [ether('100'), ether('-100')]); + await expect(tx).to.changeTokenBalances(weth, [owner, alice], [ether('-0.1'), ether('0.1')]); + }); }); }); From 16ebdd25885071156bb2ea1f8310aa17f1fe209a Mon Sep 17 00:00:00 2001 From: Denis Date: Thu, 26 Oct 2023 00:55:51 +0400 Subject: [PATCH 19/32] Remove deprecated todo --- test/MeasureGas.js | 2 -- test/WhitelistChecker.js | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/test/MeasureGas.js b/test/MeasureGas.js index 7c69299d..662bf32b 100644 --- a/test/MeasureGas.js +++ b/test/MeasureGas.js @@ -303,7 +303,6 @@ describe('MeasureGas', function () { }); await weth.transfer(resolver.address, ether('0.1')); - await resolver.approve(weth.address, lopv4.address); const tx = await resolver.settleOrders( lopv4.interface.encodeFunctionData('fillOrderArgs', [ @@ -367,7 +366,6 @@ describe('MeasureGas', function () { }); await weth.approve(resolver.address, ether('0.1')); - await resolver.approve(weth.address, lopv4.address); const tx = await resolver.settleOrders( lopv4.interface.encodeFunctionData('fillOrderArgs', [ diff --git a/test/WhitelistChecker.js b/test/WhitelistChecker.js index 4432d928..6d60bea7 100644 --- a/test/WhitelistChecker.js +++ b/test/WhitelistChecker.js @@ -5,7 +5,7 @@ const { buildOrder, buildMakerTraits } = require('@1inch/limit-order-protocol-co const { initContractsForSettlement } = require('./helpers/fixtures'); const { buildCalldataForOrder } = require('./helpers/fusionUtils'); -describe('WhitelistChecker // TODO: Update this tests', function () { +describe('WhitelistChecker', function () { describe('should not work with non-whitelisted address', function () { it('whitelist check in postInteraction method', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); From dafd979fa08452419fc50de02d813028b0ac121d Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 27 Oct 2023 01:02:53 +0400 Subject: [PATCH 20/32] Refactored tests --- test/Settlement.js | 229 ++++++++++++++---------------------- test/WhitelistChecker.js | 20 ++-- test/helpers/fixtures.js | 9 +- test/helpers/fusionUtils.js | 32 +++-- 4 files changed, 131 insertions(+), 159 deletions(-) diff --git a/test/Settlement.js b/test/Settlement.js index 969857f7..793093dd 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -1,9 +1,8 @@ -const { ethers } = require('hardhat'); const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { time, expect, ether, trim0x, timeIncreaseTo, getPermit, getPermit2, compressPermit, permit2Contract } = require('@1inch/solidity-utils'); const { buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); const { initContractsForSettlement } = require('./helpers/fixtures'); -const { buildCalldataForOrder } = require('./helpers/fusionUtils'); +const { buildAuctionDetails, buildCalldataForOrder } = require('./helpers/fusionUtils'); const ORDER_FEE = 100n; const BACK_ORDER_FEE = 125n; @@ -12,10 +11,12 @@ const BASE_POINTS = ether('0.001'); // 1e15 describe('Settlement', function () { it('opposite direction recursive swap', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, - } = dataFormFixture; + } = setupData; const fillOrderToData1 = await buildCalldataForOrder({ orderData: { @@ -27,7 +28,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('100'), isInnermostOrder: true, isMakingAmount: false, @@ -43,7 +44,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: owner, - dataFormFixture, + setupData, minReturn: ether('0.11'), additionalDataForSettlement: fillOrderToData1, isMakingAmount: false, @@ -56,11 +57,13 @@ describe('Settlement', function () { it('settle orders with permits, permit', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, lopv4, resolver }, accounts: { owner, alice }, others: { chainId }, - } = dataFormFixture; + } = setupData; const fillOrderToData1 = await buildCalldataForOrder({ orderData: { @@ -72,7 +75,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('100'), isInnermostOrder: true, isMakingAmount: false, @@ -88,7 +91,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: owner, - dataFormFixture, + setupData, minReturn: ether('0.11'), additionalDataForSettlement: fillOrderToData1, isMakingAmount: false, @@ -106,11 +109,13 @@ describe('Settlement', function () { it('settle orders with permits, permit2', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, lopv4, resolver }, accounts: { owner, alice }, others: { chainId }, - } = dataFormFixture; + } = setupData; const fillOrderToData1 = await buildCalldataForOrder({ orderData: { @@ -122,7 +127,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('100'), isInnermostOrder: true, isMakingAmount: false, @@ -138,7 +143,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: owner, - dataFormFixture, + setupData, minReturn: ether('0.11'), additionalDataForSettlement: fillOrderToData1, isMakingAmount: false, @@ -160,10 +165,12 @@ describe('Settlement', function () { it('opposite direction recursive swap with taking fee', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, settlement, resolver }, accounts: { owner, alice, bob }, - } = dataFormFixture; + } = setupData; const fillOrderToData1 = await buildCalldataForOrder({ orderData: { @@ -175,7 +182,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('100'), isInnermostOrder: true, isMakingAmount: false, @@ -194,7 +201,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: owner, - dataFormFixture, + setupData, minReturn: ether('0.11'), additionalDataForSettlement: fillOrderToData1, isMakingAmount: false, @@ -219,11 +226,13 @@ describe('Settlement', function () { it('unidirectional recursive swap', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, others: { abiCoder }, - } = dataFormFixture; + } = setupData; const resolverArgs = abiCoder.encode( ['address[]', 'bytes[]'], @@ -249,7 +258,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('15'), additionalDataForSettlement: resolverArgs, isInnermostOrder: true, @@ -266,7 +275,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('10'), additionalDataForSettlement: fillOrderToData1, isMakingAmount: false, @@ -281,10 +290,12 @@ describe('Settlement', function () { it('triple recursive swap', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, - } = dataFormFixture; + } = setupData; const fillOrderToData2 = await buildCalldataForOrder({ orderData: { @@ -296,7 +307,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: owner, - dataFormFixture, + setupData, minReturn: ether('0.025'), isInnermostOrder: true, isMakingAmount: false, @@ -312,7 +323,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('15'), additionalDataForSettlement: fillOrderToData2, isMakingAmount: false, @@ -328,7 +339,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('10'), additionalDataForSettlement: fillOrderToData1, isMakingAmount: false, @@ -341,32 +352,28 @@ describe('Settlement', function () { describe('dutch auction params', function () { const prepareSingleOrder = async ({ - startTime, - auctionDelay = 0, - initialRateBump = 1000000n, - auctionDuration = 1800, targetTakingAmount = 0n, - points = [], - dataFormFixture, + setupData, }) => { const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, others: { abiCoder }, - } = dataFormFixture; + auction: { startTime, delay, duration, initialRateBump }, + } = setupData; let actualTakingAmount = targetTakingAmount; if (actualTakingAmount === 0n) { actualTakingAmount = ether('0.1'); const ts = await time.latest(); // TODO: avoid this shit (as well as any other computations in tests) - if (ts < startTime + auctionDelay + auctionDuration) { + if (ts < startTime + delay + duration) { // actualTakingAmount = actualTakingAmount * ( - // _BASE_POINTS + initialRateBump * (startTime + auctionDelay + auctionDuration - currentTimestamp) / auctionDuration + // _BASE_POINTS + initialRateBump * (startTime + delay + duration - currentTimestamp) / duration // ) / _BASE_POINTS - const minDuration = startTime + auctionDelay + auctionDuration - ts > auctionDuration ? auctionDuration : startTime + auctionDelay + auctionDuration - ts - 2; + const minDuration = startTime + delay + duration - ts > duration ? duration : startTime + delay + duration - ts - 2; actualTakingAmount = - (actualTakingAmount * (10000000n + (BigInt(initialRateBump) * BigInt(minDuration)) / BigInt(auctionDuration))) / + (actualTakingAmount * (10000000n + (BigInt(initialRateBump) * BigInt(minDuration)) / BigInt(duration))) / 10000000n; } } @@ -385,13 +392,6 @@ describe('Settlement', function () { ], ); - let auctionDetails = ethers.utils.solidityPack( - ['uint32', 'uint24', 'uint24'], [startTime + auctionDelay, time.duration.hours(1), initialRateBump], - ); - for (let i = 0; i < points.length; i++) { - auctionDetails += trim0x(ethers.utils.solidityPack(['uint24', 'uint16'], [points[i][0], points[i][1]])); - } - const fillOrderToData = await buildCalldataForOrder({ orderData: { maker: alice.address, @@ -402,13 +402,12 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('100'), additionalDataForSettlement: resolverCalldata, isInnermostOrder: true, isMakingAmount: false, fillingAmount: actualTakingAmount, - auctionDetails, }); await weth.approve(resolver.address, actualTakingAmount); @@ -417,66 +416,58 @@ describe('Settlement', function () { it('matching order before orderTime has maximal rate bump', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails({ delay: 60, initialRateBump: 1000000n }); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, - } = dataFormFixture; + } = setupData; - const fillOrderToData = await prepareSingleOrder({ - startTime: dataFormFixture.others.auctionStartTime, - auctionDelay: 60, // seconds - dataFormFixture, - }); + const fillOrderToData = await prepareSingleOrder({ setupData }); const txn = await resolver.settleOrders(fillOrderToData); await expect(txn).to.changeTokenBalances(dai, [resolver, alice], [ether('100'), ether('-100')]); await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('-0.11'), ether('0.11')]); }); - describe.skip('order with one bump point', async function () { - it('matching order before bump point', async function () { + describe('order with one bump point', async function () { + it.skip('matching order before bump point', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails({ initialRateBump: 10000n, points: [[240, 9000]] }); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, - } = dataFormFixture; + } = setupData; - const startTime = await time.latest(); const actualTakingAmount = ether('0.109'); const fillOrderToData = await prepareSingleOrder({ - startTime, - initialRateBump: 10000n, - auctionDuration: 1800, - points: [[240, 9000]], targetTakingAmount: actualTakingAmount, - dataFormFixture, + setupData, }); - await timeIncreaseTo(startTime + 239); + await timeIncreaseTo(setupData.auction.startTime + 239); const txn = await resolver.settleOrders(fillOrderToData); await expect(txn).to.changeTokenBalances(dai, [resolver, alice], [ether('100'), ether('-100')]); await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('-0.109'), ether('0.109')]); }); - it('matching order after bump point', async function () { + it.skip('matching order after bump point', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails({ initialRateBump: 10000n, points: [[240, 9000n]] }); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, - } = dataFormFixture; + } = setupData; - const startTime = await time.latest(); const actualTakingAmount = ether('0.106'); const fillOrderToData = await prepareSingleOrder({ - startTime, - initialRateBump: 1000000n, - auctionDuration: 1800, - points: [[240, 900000n]], targetTakingAmount: actualTakingAmount, - dataFormFixture, + setupData, }); - await timeIncreaseTo(startTime + 759); + await timeIncreaseTo(setupData.auction.startTime + 759); const txn = await resolver.settleOrders(fillOrderToData); await expect(txn).to.changeTokenBalances(dai, [resolver, alice], [ether('100'), ether('-100')]); @@ -486,17 +477,14 @@ describe('Settlement', function () { it('set initial rate', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails({ delay: 60, initialRateBump: 2000000n }); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, - } = dataFormFixture; + } = setupData; - const fillOrderToData = await prepareSingleOrder({ - startTime: await time.latest(), - auctionDelay: 60, - initialRateBump: 2000000n, - dataFormFixture, - }); + const fillOrderToData = await prepareSingleOrder({ setupData }); const txn = await resolver.settleOrders(fillOrderToData); await expect(txn).to.changeTokenBalances(dai, [resolver, alice], [ether('100'), ether('-100')]); @@ -505,18 +493,18 @@ describe('Settlement', function () { it.skip('set auctionDuration', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + + const normalizeTime = Math.floor(((await time.latest()) + 59) / 60) * 60; + const auction = await buildAuctionDetails({ startTime: normalizeTime - 448, duration: 900, initialRateBump: 1000000n }); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, - } = dataFormFixture; + } = setupData; - const normalizeTime = Math.floor(((await time.latest()) + 59) / 60) * 60; await time.increaseTo(normalizeTime); const fillOrderToData = await prepareSingleOrder({ - startTime: normalizeTime - 448, - initialRateBump: 1000000n, - auctionDuration: 900, - dataFormFixture, + setupData, }); const txn = await resolver.settleOrders(fillOrderToData); @@ -527,10 +515,12 @@ describe('Settlement', function () { it('should change availableCredit with non-zero fee', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, settlement, resolver }, accounts: { owner, alice }, - } = dataFormFixture; + } = setupData; const fillOrderToData1 = await buildCalldataForOrder({ orderData: { @@ -542,7 +532,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('0.1'), isInnermostOrder: true, isMakingAmount: false, @@ -560,7 +550,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: owner, - dataFormFixture, + setupData, minReturn: ether('100'), additionalDataForSettlement: fillOrderToData1, isMakingAmount: false, @@ -577,11 +567,13 @@ describe('Settlement', function () { it('partial fill with taking fee', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, settlement, resolver }, accounts: { owner, alice }, others: { abiCoder }, - } = dataFormFixture; + } = setupData; const partialModifier = 40n; const points = 100n; @@ -610,7 +602,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('0.01') * partialModifier / points, additionalDataForSettlement: resolverArgs, isInnermostOrder: true, @@ -632,11 +624,13 @@ describe('Settlement', function () { it('resolver should pay minimal 1 wei fee', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, settlement, resolver }, accounts: { owner, alice }, others: { abiCoder }, - } = dataFormFixture; + } = setupData; const minimalPartialModifier = 1n; const points = ether('0.01'); @@ -666,7 +660,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('0.01'), additionalDataForSettlement: resolverArgs, isInnermostOrder: true, @@ -688,11 +682,12 @@ describe('Settlement', function () { it('should not change when availableCredit is not enough', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, - others: { BACK_ORDER_FEE }, - } = dataFormFixture; + } = setupData; const fillOrderToData1 = await buildCalldataForOrder({ orderData: { @@ -704,7 +699,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('100'), isInnermostOrder: true, feeType: 1, @@ -721,7 +716,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: owner, - dataFormFixture, + setupData, minReturn: ether('0.1'), additionalDataForSettlement: fillOrderToData1, feeType: 1, @@ -740,12 +735,13 @@ describe('Settlement', function () { describe('whitelist lock period', async function () { it('should change only after whitelistedCutOff', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails({ startTime: await time.latest() + time.duration.hours('3') }); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, - } = dataFormFixture; + } = setupData; - dataFormFixture.others.auctionStartTime += time.duration.hours('3'); const fillOrderToData1 = await buildCalldataForOrder({ orderData: { maker: alice.address, @@ -756,7 +752,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('100'), isInnermostOrder: true, }); @@ -771,7 +767,7 @@ describe('Settlement', function () { makerTraits: buildMakerTraits(), }, orderSigner: owner, - dataFormFixture, + setupData, minReturn: ether('0.1'), additionalDataForSettlement: fillOrderToData1, }); @@ -784,51 +780,8 @@ describe('Settlement', function () { expect(e.message).to.include('0xfac829a0'); // ResolverIsNotWhitelisted() } - await timeIncreaseTo(dataFormFixture.others.auctionStartTime + 1); - - await resolver.settleOrders(fillOrderToData0); - }); - - it.skip('should change by non-whitelisted resolver after publicCutOff', async function () { - const dataFormFixture = await loadFixture(initContractsForSettlement); - const { - contracts: { dai, weth, settlement, resolver }, - accounts: { owner, alice }, - } = dataFormFixture; - - const fillOrderToData1 = await buildCalldataForOrder({ - orderData: { - maker: alice.address, - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.1'), - takingAmount: ether('100'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), - }, - singleFusionData: { publicTimeDelay: 60n, resolverFee: BACK_ORDER_FEE }, - orderSigner: alice, - dataFormFixture, - isInnermostOrder: true, - }); - - const fillOrderToData0 = await buildCalldataForOrder({ - orderData: { - maker: owner.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), - makerTraits: buildMakerTraits({ allowedSender: settlement.address }), - }, - singleFusionData: { publicTimeDelay: 60n, resolverFee: ORDER_FEE }, - orderSigner: owner, - dataFormFixture, - additionalDataForSettlement: fillOrderToData1, - needAddResolvers: true, - }); + await timeIncreaseTo(setupData.auction.startTime + 1); - await expect(resolver.settleOrders(fillOrderToData0)).to.be.revertedWithCustomError(settlement, 'ResolverIsNotWhitelisted'); - await timeIncreaseTo(BigInt(await time.latest()) + 100n); await resolver.settleOrders(fillOrderToData0); }); }); diff --git a/test/WhitelistChecker.js b/test/WhitelistChecker.js index 6d60bea7..2454b8c5 100644 --- a/test/WhitelistChecker.js +++ b/test/WhitelistChecker.js @@ -3,16 +3,18 @@ const { loadFixture } = require('@nomicfoundation/hardhat-network-helpers'); const { expect, ether, constants } = require('@1inch/solidity-utils'); const { buildOrder, buildMakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); const { initContractsForSettlement } = require('./helpers/fixtures'); -const { buildCalldataForOrder } = require('./helpers/fusionUtils'); +const { buildAuctionDetails, buildCalldataForOrder } = require('./helpers/fusionUtils'); describe('WhitelistChecker', function () { describe('should not work with non-whitelisted address', function () { it('whitelist check in postInteraction method', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { alice }, - } = dataFormFixture; + } = setupData; weth.transfer(resolver.address, ether('0.1')); @@ -26,7 +28,7 @@ describe('WhitelistChecker', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('0.1'), isInnermostOrder: true, whitelistData: '0x' + constants.ZERO_ADDRESS.substring(22), @@ -43,10 +45,12 @@ describe('WhitelistChecker', function () { it('only resolver can use takerInteraction method', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver, settlement, lopv4 }, accounts: { alice }, - } = dataFormFixture; + } = setupData; // Deploy another resolver const ResolverMock = await ethers.getContractFactory('ResolverMock'); @@ -62,7 +66,7 @@ describe('WhitelistChecker', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('0.1'), isInnermostOrder: true, }); @@ -103,10 +107,12 @@ describe('WhitelistChecker', function () { describe('should work with whitelisted address', function () { it('whitelist check in settleOrders method', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails(); + const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { alice }, - } = dataFormFixture; + } = setupData; weth.transfer(resolver.address, ether('0.1')); @@ -120,7 +126,7 @@ describe('WhitelistChecker', function () { makerTraits: buildMakerTraits(), }, orderSigner: alice, - dataFormFixture, + setupData, minReturn: ether('0.1'), isInnermostOrder: true, whitelistData: '0x' + resolver.address.substring(22), diff --git a/test/helpers/fixtures.js b/test/helpers/fixtures.js index 230cc11d..034657eb 100644 --- a/test/helpers/fixtures.js +++ b/test/helpers/fixtures.js @@ -1,7 +1,7 @@ const fs = require('fs'); const path = require('path'); const { ethers } = require('hardhat'); -const { ether, deployContract, time } = require('@1inch/solidity-utils'); +const { ether, deployContract } = require('@1inch/solidity-utils'); async function getChainId() { return (await ethers.provider.getNetwork()).chainId; @@ -51,15 +51,10 @@ async function initContractsForSettlement() { await resolver.approve(dai.address, lopv4.address); await resolver.approve(weth.address, lopv4.address); - const auctionStartTime = await time.latest(); - const auctionDetails = ethers.utils.solidityPack( - ['uint32', 'uint24', 'uint24'], [auctionStartTime, time.duration.hours(1), 0], - ); - return { contracts: { dai, weth, lopv4, settlement, feeBank, resolver }, accounts: { owner, alice, bob }, - others: { chainId, abiCoder, auctionStartTime, auctionDetails }, + others: { chainId, abiCoder }, }; } diff --git a/test/helpers/fusionUtils.js b/test/helpers/fusionUtils.js index 5f3aa077..6ac76b7a 100644 --- a/test/helpers/fusionUtils.js +++ b/test/helpers/fusionUtils.js @@ -1,12 +1,12 @@ -const { trim0x } = require('@1inch/solidity-utils'); +const { time, trim0x } = require('@1inch/solidity-utils'); const { ethers } = require('hardhat'); -const { buildOrder, signOrder, buildTakerTraits } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); +const { buildOrder, buildTakerTraits, signOrder } = require('@1inch/limit-order-protocol-contract/test/helpers/orderUtils'); async function buildCalldataForOrder({ orderData, orderSigner, minReturn, - dataFormFixture, + setupData, additionalDataForSettlement = '', isInnermostOrder = false, isMakingAmount = true, @@ -14,13 +14,13 @@ async function buildCalldataForOrder({ feeType = 0, integrator = orderSigner.address, resolverFee = 0, - auctionDetails = dataFormFixture.others.auctionDetails, - whitelistData = '0x' + dataFormFixture.contracts.resolver.address.substring(22), + whitelistData = '0x' + setupData.contracts.resolver.address.substring(22), }) { const { contracts: { lopv4, settlement, resolver }, - others: { chainId, auctionStartTime }, - } = dataFormFixture; + others: { chainId }, + auction: { startTime: auctionStartTime, details: auctionDetails }, + } = setupData; let postInteractionFeeDataTypes = ['uint8']; let postInteractionFeeData = [0]; @@ -63,6 +63,24 @@ async function buildCalldataForOrder({ ]); } +async function buildAuctionDetails({ + startTime, // default is time.latest() + duration = 1800, // default is 30 minutes + delay = 0, + initialRateBump = 0, + points = [], +} = {}) { + startTime = startTime || await time.latest(); + let details = ethers.utils.solidityPack( + ['uint32', 'uint24', 'uint24'], [startTime + delay, duration, initialRateBump], + ); + for (let i = 0; i < points.length; i++) { + details += trim0x(ethers.utils.solidityPack(['uint24', 'uint16'], [points[i][0], points[i][1]])); + } + return { startTime, details, delay, duration, initialRateBump }; +} + module.exports = { + buildAuctionDetails, buildCalldataForOrder, }; From 9587d917fe1b579d61e4fb64190237b2f994fec2 Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 27 Oct 2023 01:03:47 +0400 Subject: [PATCH 21/32] Fix getrateBump --- contracts/SettlementExtension.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/SettlementExtension.sol b/contracts/SettlementExtension.sol index a5499198..8eebf7ba 100644 --- a/contracts/SettlementExtension.sol +++ b/contracts/SettlementExtension.sol @@ -101,7 +101,7 @@ contract SettlementExtension is IPostInteraction, IAmountGetter, FeeBankCharger } currentRateBump = nextRateBump; currentPointTime = nextPointTime; - // auctionDetails = auctionDetails[5:]; + auctionDetails = auctionDetails[5:]; } return (auctionFinishTime - block.timestamp) * currentRateBump / (auctionFinishTime - currentPointTime); From 44968853196f613bacd39cf480afbb6632b7ed95 Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 27 Oct 2023 11:56:32 +0400 Subject: [PATCH 22/32] Fix and add test with points --- contracts/SettlementExtension.sol | 6 +-- test/Settlement.js | 63 ++++++++++++++++++++++++------- 2 files changed, 52 insertions(+), 17 deletions(-) diff --git a/contracts/SettlementExtension.sol b/contracts/SettlementExtension.sol index 8eebf7ba..c48a504b 100644 --- a/contracts/SettlementExtension.sol +++ b/contracts/SettlementExtension.sol @@ -94,16 +94,14 @@ contract SettlementExtension is IPostInteraction, IAmountGetter, FeeBankCharger uint256 currentRateBump = initialRateBump; for (uint256 i = 0; i < pointsSize; i++) { - uint256 nextRateBump = uint24(bytes3(auctionDetails[:3])); - uint256 nextPointTime = currentPointTime + uint16(bytes2(auctionDetails[3:5])); + uint256 nextRateBump = uint24(bytes3(auctionDetails[i*5:i*5+3])); + uint256 nextPointTime = currentPointTime + uint16(bytes2(auctionDetails[i*5+3:5*(i+1)])); if (block.timestamp <= nextPointTime) { return ((block.timestamp - currentPointTime) * nextRateBump + (nextPointTime - block.timestamp) * currentRateBump) / (nextPointTime - currentPointTime); } currentRateBump = nextRateBump; currentPointTime = nextPointTime; - auctionDetails = auctionDetails[5:]; } - return (auctionFinishTime - block.timestamp) * currentRateBump / (auctionFinishTime - currentPointTime); } diff --git a/test/Settlement.js b/test/Settlement.js index 793093dd..5f2f7d2e 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -371,7 +371,7 @@ describe('Settlement', function () { // actualTakingAmount = actualTakingAmount * ( // _BASE_POINTS + initialRateBump * (startTime + delay + duration - currentTimestamp) / duration // ) / _BASE_POINTS - const minDuration = startTime + delay + duration - ts > duration ? duration : startTime + delay + duration - ts - 2; + const minDuration = startTime + delay + duration - ts > duration ? duration : startTime + delay + duration - ts - 3; actualTakingAmount = (actualTakingAmount * (10000000n + (BigInt(initialRateBump) * BigInt(minDuration)) / BigInt(duration))) / 10000000n; @@ -431,18 +431,17 @@ describe('Settlement', function () { }); describe('order with one bump point', async function () { - it.skip('matching order before bump point', async function () { + it('matching order equal to bump point', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); - const auction = await buildAuctionDetails({ initialRateBump: 10000n, points: [[240, 9000]] }); + const auction = await buildAuctionDetails({ points: [[900000, 240]] }); const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, } = setupData; - const actualTakingAmount = ether('0.109'); const fillOrderToData = await prepareSingleOrder({ - targetTakingAmount: actualTakingAmount, + targetTakingAmount: ether('0.109'), setupData, }); @@ -453,18 +452,38 @@ describe('Settlement', function () { await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('-0.109'), ether('0.109')]); }); - it.skip('matching order after bump point', async function () { + it('matching order before bump point', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); - const auction = await buildAuctionDetails({ initialRateBump: 10000n, points: [[240, 9000n]] }); + const auction = await buildAuctionDetails({ initialRateBump: 1000000n, points: [[900000, 240]] }); const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, } = setupData; - const actualTakingAmount = ether('0.106'); const fillOrderToData = await prepareSingleOrder({ - targetTakingAmount: actualTakingAmount, + targetTakingAmount: ether('0.1095'), // 1/2 * (takingAmount * 10%) + 1/2 * (takingAmount * 9%) + setupData, + }); + + await timeIncreaseTo(setupData.auction.startTime + 240 / 2 - 1); + + const txn = await resolver.settleOrders(fillOrderToData); + await expect(txn).to.changeTokenBalances(dai, [resolver, alice], [ether('100'), ether('-100')]); + await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('-0.1095'), ether('0.1095')]); + }); + + it('matching order after bump point', async function () { + const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails({ points: [[900000, 240]] }); + const setupData = { ...dataFormFixture, auction }; + const { + contracts: { dai, weth, resolver }, + accounts: { owner, alice }, + } = setupData; + + const fillOrderToData = await prepareSingleOrder({ + targetTakingAmount: ether('0.106'), setupData, }); await timeIncreaseTo(setupData.auction.startTime + 759); @@ -473,6 +492,26 @@ describe('Settlement', function () { await expect(txn).to.changeTokenBalances(dai, [resolver, alice], [ether('100'), ether('-100')]); await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('-0.106'), ether('0.106')]); }); + + it('matching order between 2 bump point', async function () { + const dataFormFixture = await loadFixture(initContractsForSettlement); + const auction = await buildAuctionDetails({ points: [[500000, 240], [100000, 1240]] }); + const setupData = { ...dataFormFixture, auction }; + const { + contracts: { dai, weth, resolver }, + accounts: { owner, alice }, + } = setupData; + + const fillOrderToData = await prepareSingleOrder({ + targetTakingAmount: ether('0.103'), + setupData, + }); + await timeIncreaseTo(setupData.auction.startTime + 859); + + const txn = await resolver.settleOrders(fillOrderToData); + await expect(txn).to.changeTokenBalances(dai, [resolver, alice], [ether('100'), ether('-100')]); + await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('-0.103'), ether('0.103')]); + }); }); it('set initial rate', async function () { @@ -491,18 +530,16 @@ describe('Settlement', function () { await expect(txn).to.changeTokenBalances(weth, [owner, alice], [ether('-0.12'), ether('0.12')]); }); - it.skip('set auctionDuration', async function () { + it('set auctionDuration', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); - const normalizeTime = Math.floor(((await time.latest()) + 59) / 60) * 60; - const auction = await buildAuctionDetails({ startTime: normalizeTime - 448, duration: 900, initialRateBump: 1000000n }); + const auction = await buildAuctionDetails({ startTime: (await time.latest()) - (450 - 3), duration: 900, initialRateBump: 1000000n }); const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, } = setupData; - await time.increaseTo(normalizeTime); const fillOrderToData = await prepareSingleOrder({ setupData, }); From 66eeb674b71c059d1393162ad564edf3082b629c Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 27 Oct 2023 13:31:22 +0400 Subject: [PATCH 23/32] Try to fix CI tests --- test/Settlement.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/Settlement.js b/test/Settlement.js index 5f2f7d2e..79610106 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -533,13 +533,15 @@ describe('Settlement', function () { it('set auctionDuration', async function () { const dataFormFixture = await loadFixture(initContractsForSettlement); - const auction = await buildAuctionDetails({ startTime: (await time.latest()) - (450 - 3), duration: 900, initialRateBump: 1000000n }); + const normalizeTime = Math.floor(((await time.latest()) + 59) / 60) * 60; + const auction = await buildAuctionDetails({ startTime: normalizeTime - (450 - 3), duration: 900, initialRateBump: 1000000n }); const setupData = { ...dataFormFixture, auction }; const { contracts: { dai, weth, resolver }, accounts: { owner, alice }, } = setupData; + await time.increaseTo(normalizeTime); const fillOrderToData = await prepareSingleOrder({ setupData, }); From 636f07db2e6a68ff39aa66f714aa749be5c78acf Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 27 Oct 2023 16:12:58 +0400 Subject: [PATCH 24/32] Refactor --- contracts/SettlementExtension.sol | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/SettlementExtension.sol b/contracts/SettlementExtension.sol index c48a504b..19d6467f 100644 --- a/contracts/SettlementExtension.sol +++ b/contracts/SettlementExtension.sol @@ -94,13 +94,14 @@ contract SettlementExtension is IPostInteraction, IAmountGetter, FeeBankCharger uint256 currentRateBump = initialRateBump; for (uint256 i = 0; i < pointsSize; i++) { - uint256 nextRateBump = uint24(bytes3(auctionDetails[i*5:i*5+3])); - uint256 nextPointTime = currentPointTime + uint16(bytes2(auctionDetails[i*5+3:5*(i+1)])); + uint256 nextRateBump = uint24(bytes3(auctionDetails[:3])); + uint256 nextPointTime = currentPointTime + uint16(bytes2(auctionDetails[3:5])); if (block.timestamp <= nextPointTime) { return ((block.timestamp - currentPointTime) * nextRateBump + (nextPointTime - block.timestamp) * currentRateBump) / (nextPointTime - currentPointTime); } currentRateBump = nextRateBump; currentPointTime = nextPointTime; + auctionDetails = auctionDetails[5:]; } return (auctionFinishTime - block.timestamp) * currentRateBump / (auctionFinishTime - currentPointTime); } From 277137aa2779b6be0abfd233b2960143a2e08620 Mon Sep 17 00:00:00 2001 From: Denis Date: Sat, 28 Oct 2023 00:42:29 +0400 Subject: [PATCH 25/32] Refactor ResolverMock --- contracts/interfaces/ISettlement.sol | 10 ------- contracts/mocks/ResolverMock.sol | 42 ++++++++++------------------ 2 files changed, 14 insertions(+), 38 deletions(-) delete mode 100644 contracts/interfaces/ISettlement.sol diff --git a/contracts/interfaces/ISettlement.sol b/contracts/interfaces/ISettlement.sol deleted file mode 100644 index 6e8a80c1..00000000 --- a/contracts/interfaces/ISettlement.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.19; - -import "@1inch/limit-order-protocol-contract/contracts/interfaces/ITakerInteraction.sol"; -import "./IFeeBankCharger.sol"; - -interface ISettlement is ITakerInteraction, IFeeBankCharger { - function settleOrders(bytes calldata order) external returns(bool); -} diff --git a/contracts/mocks/ResolverMock.sol b/contracts/mocks/ResolverMock.sol index f8c963d0..7441046e 100644 --- a/contracts/mocks/ResolverMock.sol +++ b/contracts/mocks/ResolverMock.sol @@ -2,14 +2,10 @@ pragma solidity 0.8.19; -import "@openzeppelin/contracts/interfaces/IERC1271.sol"; import "../interfaces/IResolver.sol"; -import "../interfaces/ISettlement.sol"; import "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol"; -import "@1inch/solidity-utils/contracts/libraries/ECDSA.sol"; -import "@1inch/limit-order-protocol-contract/contracts/interfaces/IOrderMixin.sol"; -contract ResolverMock is IResolver, IERC1271 { +contract ResolverMock is IResolver { error OnlyOwner(); error NotTaker(); error OnlyLOP(); @@ -19,50 +15,41 @@ contract ResolverMock is IResolver, IERC1271 { using AddressLib for Address; bytes1 private constant _FINALIZE_INTERACTION = 0x01; - uint256 private constant _RESOLVER_ADDRESS_BYTES_SIZE = 10; - uint256 private constant _BASE_POINTS = 10_000_000; // 100% - uint256 private constant _TAKING_FEE_BASE = 1e9; - uint256 private constant _TAKING_FEE_RATIO_OFFSET = 160; - address private immutable _settlementExtension; IOrderMixin private immutable _lopv4; address private immutable _owner; + modifier onlyOwner () { + if (msg.sender != _owner) revert OnlyOwner(); + _; + } + constructor(address settlementExtension, IOrderMixin limitOrderProtocol) { _settlementExtension = settlementExtension; _lopv4 = limitOrderProtocol; _owner = msg.sender; } - function isValidSignature(bytes32 hash, bytes calldata signature) external view returns (bytes4 magicValue) { - if (ECDSA.recoverOrIsValidSignature(_owner, hash, signature)) { - return IERC1271.isValidSignature.selector; - } - return 0xFFFFFFFF; + function approve(IERC20 token, address to) external onlyOwner { + token.forceApprove(to, type(uint256).max); } - function approve(IERC20 token, address to) external { - if (msg.sender != _owner) revert OnlyOwner(); - token.forceApprove(to, type(uint256).max); + function settleOrders(bytes calldata data) external onlyOwner() { + _settleOrders(data); } - function settleOrders(bytes calldata data) public { - if (msg.sender != _owner) revert OnlyOwner(); + // @dev High byte of `packing` contains number of permits, each 2 bits from lowest contains length of permit (index in [92,120,148] array) + function settleOrdersWithPermits(bytes calldata data, uint256 packing, bytes calldata packedPermits) external onlyOwner { + _performPermits(packing, packedPermits); _settleOrders(data); } function _settleOrders(bytes calldata data) internal { - (bool success, bytes memory reason) = address(_lopv4).call(data); // abi.encodeWithSelector(_lopv4.fillOrderArgs.selector, data) + (bool success, bytes memory reason) = address(_lopv4).call(data); if (!success) revert FailedExternalCall(0, reason); } - // @dev High byte of `packing` contains number of permits, each 2 bits from lowest contains length of permit (index in [92,120,148] array) - function settleOrdersWithPermits(bytes calldata data, uint256 packing, bytes calldata packedPermits) external { - _performPermits(packing, packedPermits); - settleOrders(data); - } - function takerInteraction( IOrderMixin.Order calldata /* order */, bytes calldata /* extension */, @@ -87,7 +74,6 @@ contract ResolverMock is IResolver, IERC1271 { } } } else { - // _lopv4.call(abi.encodeWithSelector(extraData[1:4], args[5:])); _settleOrders(extraData[1:]); } } From 8027e26cb42d922b28d4a99ef008ef37db5e6d03 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Wed, 1 Nov 2023 13:00:22 +0400 Subject: [PATCH 26/32] simplify --- contracts/interfaces/IResolver.sol | 18 ------------------ contracts/mocks/ResolverMock.sol | 4 ++-- 2 files changed, 2 insertions(+), 20 deletions(-) delete mode 100644 contracts/interfaces/IResolver.sol diff --git a/contracts/interfaces/IResolver.sol b/contracts/interfaces/IResolver.sol deleted file mode 100644 index 9f0abc95..00000000 --- a/contracts/interfaces/IResolver.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.19; - -import "@1inch/limit-order-protocol-contract/contracts/interfaces/IOrderMixin.sol"; - -interface IResolver { - function takerInteraction( - IOrderMixin.Order calldata order, - bytes calldata extension, - bytes32 orderHash , - address taker, - uint256 makingAmount, - uint256 takingAmount, - uint256 remainingMakingAmount, - bytes calldata extraData - ) external; -} diff --git a/contracts/mocks/ResolverMock.sol b/contracts/mocks/ResolverMock.sol index 7441046e..552afe18 100644 --- a/contracts/mocks/ResolverMock.sol +++ b/contracts/mocks/ResolverMock.sol @@ -2,10 +2,10 @@ pragma solidity 0.8.19; -import "../interfaces/IResolver.sol"; import "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol"; +import "@1inch/limit-order-protocol-contract/contracts/interfaces/ITakerInteraction.sol"; -contract ResolverMock is IResolver { +contract ResolverMock is ITakerInteraction { error OnlyOwner(); error NotTaker(); error OnlyLOP(); From 224b225fbc467eef7e99abfebe8fe36ac6d270c9 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Wed, 1 Nov 2023 13:00:28 +0400 Subject: [PATCH 27/32] linter --- contracts/mocks/ResolverMock.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/mocks/ResolverMock.sol b/contracts/mocks/ResolverMock.sol index 552afe18..23960ce2 100644 --- a/contracts/mocks/ResolverMock.sol +++ b/contracts/mocks/ResolverMock.sol @@ -46,6 +46,7 @@ contract ResolverMock is ITakerInteraction { } function _settleOrders(bytes calldata data) internal { + // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory reason) = address(_lopv4).call(data); if (!success) revert FailedExternalCall(0, reason); } From 7d6f42638103a3f8515ec80676674d1b64f8afc4 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Wed, 1 Nov 2023 13:01:17 +0400 Subject: [PATCH 28/32] fix comment --- contracts/mocks/ResolverMock.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/mocks/ResolverMock.sol b/contracts/mocks/ResolverMock.sol index 23960ce2..793b3950 100644 --- a/contracts/mocks/ResolverMock.sol +++ b/contracts/mocks/ResolverMock.sol @@ -39,7 +39,7 @@ contract ResolverMock is ITakerInteraction { _settleOrders(data); } - // @dev High byte of `packing` contains number of permits, each 2 bits from lowest contains length of permit (index in [92,120,148] array) + /// @dev High byte of `packing` contains number of permits, each 2 bits from lowest contains length of permit (index in [92,120,148] array) function settleOrdersWithPermits(bytes calldata data, uint256 packing, bytes calldata packedPermits) external onlyOwner { _performPermits(packing, packedPermits); _settleOrders(data); From c37572d9e3fe21e84c00592dc11b0478f391eb00 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Wed, 1 Nov 2023 13:17:22 +0400 Subject: [PATCH 29/32] better revert handling --- contracts/mocks/ResolverMock.sol | 5 +++-- test/Settlement.js | 20 ++++++-------------- test/WhitelistChecker.js | 20 ++++++-------------- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/contracts/mocks/ResolverMock.sol b/contracts/mocks/ResolverMock.sol index 793b3950..07d0b642 100644 --- a/contracts/mocks/ResolverMock.sol +++ b/contracts/mocks/ResolverMock.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.19; import "@1inch/solidity-utils/contracts/libraries/SafeERC20.sol"; +import "@1inch/solidity-utils/contracts/libraries/RevertReasonForwarder.sol"; import "@1inch/limit-order-protocol-contract/contracts/interfaces/ITakerInteraction.sol"; contract ResolverMock is ITakerInteraction { @@ -47,8 +48,8 @@ contract ResolverMock is ITakerInteraction { function _settleOrders(bytes calldata data) internal { // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory reason) = address(_lopv4).call(data); - if (!success) revert FailedExternalCall(0, reason); + (bool success,) = address(_lopv4).call(data); + if (!success) RevertReasonForwarder.reRevert(); } function takerInteraction( diff --git a/test/Settlement.js b/test/Settlement.js index 79610106..44cef8c7 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -762,13 +762,9 @@ describe('Settlement', function () { resolverFee: '1000000', }); - try { - await resolver.settleOrders(fillOrderToData0); - expect.fail('should revert'); - } catch (e) { - expect(e.message).to.include('FailedExternalCall'); - expect(e.message).to.include('0xa7fd3792'); // NotEnoughCredit() - } + await expect(resolver.settleOrders(fillOrderToData0)).to.be.revertedWithCustomError( + dataFormFixture.contracts.settlement, 'NotEnoughCredit' + ); }); describe('whitelist lock period', async function () { @@ -811,13 +807,9 @@ describe('Settlement', function () { additionalDataForSettlement: fillOrderToData1, }); - try { - await resolver.settleOrders(fillOrderToData0); - expect.fail('should revert'); - } catch (e) { - expect(e.message).to.include('FailedExternalCall'); - expect(e.message).to.include('0xfac829a0'); // ResolverIsNotWhitelisted() - } + await expect(resolver.settleOrders(fillOrderToData0)).to.be.revertedWithCustomError( + setupData.contracts.settlement, 'ResolverIsNotWhitelisted' + ); await timeIncreaseTo(setupData.auction.startTime + 1); diff --git a/test/WhitelistChecker.js b/test/WhitelistChecker.js index 2454b8c5..628fc080 100644 --- a/test/WhitelistChecker.js +++ b/test/WhitelistChecker.js @@ -34,13 +34,9 @@ describe('WhitelistChecker', function () { whitelistData: '0x' + constants.ZERO_ADDRESS.substring(22), }); - try { - await resolver.settleOrders(fillOrderToData); - expect.fail('should revert'); - } catch (e) { - expect(e.message).to.include('FailedExternalCall'); - expect(e.message).to.include('0x4b576069'); // ResolverIsNotWhitelisted() - } + await expect(resolver.settleOrders(fillOrderToData)).to.be.revertedWithCustomError( + dataFormFixture.contracts.settlement, 'ResolverIsNotWhitelisted' + ); }); it('only resolver can use takerInteraction method', async function () { @@ -74,13 +70,9 @@ describe('WhitelistChecker', function () { // Change resolver to fakeResolver in takerInteraction const fakeFillOrderToData = fillOrderToData.slice(0, fillOrderToData.length - 86) + fakeResolver.address.substring(2) + fillOrderToData.slice(-46); - try { - await resolver.settleOrders(fakeFillOrderToData); - expect.fail('should revert'); - } catch (e) { - expect(e.message).to.include('FailedExternalCall'); - expect(e.message).to.include('0x5211a079'); // NotTaker() - } + await expect(resolver.settleOrders(fakeFillOrderToData)).to.be.revertedWithCustomError( + resolver, 'NotTaker' + ); }); it('only LOP can use takerInteraction method', async function () { From 84567ad825e7bc5658ac44a157407572e4a4c67a Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Wed, 1 Nov 2023 13:20:28 +0400 Subject: [PATCH 30/32] linter --- test/Settlement.js | 4 ++-- test/WhitelistChecker.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Settlement.js b/test/Settlement.js index 44cef8c7..0f7f83c1 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -763,7 +763,7 @@ describe('Settlement', function () { }); await expect(resolver.settleOrders(fillOrderToData0)).to.be.revertedWithCustomError( - dataFormFixture.contracts.settlement, 'NotEnoughCredit' + dataFormFixture.contracts.settlement, 'NotEnoughCredit', ); }); @@ -808,7 +808,7 @@ describe('Settlement', function () { }); await expect(resolver.settleOrders(fillOrderToData0)).to.be.revertedWithCustomError( - setupData.contracts.settlement, 'ResolverIsNotWhitelisted' + setupData.contracts.settlement, 'ResolverIsNotWhitelisted', ); await timeIncreaseTo(setupData.auction.startTime + 1); diff --git a/test/WhitelistChecker.js b/test/WhitelistChecker.js index 628fc080..52ba464c 100644 --- a/test/WhitelistChecker.js +++ b/test/WhitelistChecker.js @@ -35,7 +35,7 @@ describe('WhitelistChecker', function () { }); await expect(resolver.settleOrders(fillOrderToData)).to.be.revertedWithCustomError( - dataFormFixture.contracts.settlement, 'ResolverIsNotWhitelisted' + dataFormFixture.contracts.settlement, 'ResolverIsNotWhitelisted', ); }); @@ -71,7 +71,7 @@ describe('WhitelistChecker', function () { const fakeFillOrderToData = fillOrderToData.slice(0, fillOrderToData.length - 86) + fakeResolver.address.substring(2) + fillOrderToData.slice(-46); await expect(resolver.settleOrders(fakeFillOrderToData)).to.be.revertedWithCustomError( - resolver, 'NotTaker' + resolver, 'NotTaker', ); }); From 74c51ce95a2bc53a8904cefac13474ca2c3420d9 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Wed, 1 Nov 2023 13:40:03 +0400 Subject: [PATCH 31/32] update settlement-v1-tag --- package.json | 2 +- yarn.lock | 21 +++++++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 561957c5..786b2b0f 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "@openzeppelin/contracts": "4.8.2" }, "devDependencies": { - "@1inch/limit-order-settlement-v1": "git+https://github.com/1inch/limit-order-settlement.git#feature/settlement-v1", + "@1inch/limit-order-settlement-v1": "git+https://github.com/1inch/limit-order-settlement.git#1.0.0", "@matterlabs/hardhat-zksync-deploy": "0.6.3", "@matterlabs/hardhat-zksync-solc": "0.3.16", "@matterlabs/hardhat-zksync-verify": "0.1.4", diff --git a/yarn.lock b/yarn.lock index 5c60cdb0..897011f5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -56,14 +56,14 @@ "@chainlink/contracts" "0.6.1" "@openzeppelin/contracts" "4.9.0" -"@1inch/limit-order-settlement-v1@git+https://github.com/1inch/limit-order-settlement.git#feature/settlement-v1": +"@1inch/limit-order-settlement-v1@git+https://github.com/1inch/limit-order-settlement.git#1.0.0": version "0.0.1" - resolved "git+https://github.com/1inch/limit-order-settlement.git#7801eca16384e52705eafe3e7bcffc96223a50ed" + resolved "git+https://github.com/1inch/limit-order-settlement.git#934a8e7db4b98258c4c734566e8fcbc15b818ab5" dependencies: "@1inch/delegating" "0.0.21" - "@1inch/erc20-pods" "0.0.16" + "@1inch/erc20-pods" "0.0.17" "@1inch/limit-order-protocol-contract" "3.0.0" - "@1inch/solidity-utils" "2.2.5" + "@1inch/solidity-utils" "2.2.6" "@openzeppelin/contracts" "4.8.0" "@1inch/solidity-utils@2.2.2": @@ -118,6 +118,19 @@ ethers "5.7.1" hardhat "2.11.2" +"@1inch/solidity-utils@2.2.6": + version "2.2.6" + resolved "https://registry.yarnpkg.com/@1inch/solidity-utils/-/solidity-utils-2.2.6.tgz#79a1c2e94e5c3b29f5dfbbc8b3158deb4f292f50" + integrity sha512-XYwpPMZA5uIU5fyvkE0Zt/D4Kb/oPZCyGk3MhB8L0F3gAWbc4BD9RpUo9vEQ02K83uR5wMvB2W/Ac0Pe3YkbcQ== + dependencies: + "@metamask/eth-sig-util" "4.0.1" + "@nomicfoundation/hardhat-network-helpers" "1.0.6" + "@nomiclabs/hardhat-ethers" "2.1.1" + "@openzeppelin/contracts" "4.7.3" + ethereumjs-util "7.1.5" + ethers "5.7.1" + hardhat "2.11.2" + "@1inch/st1inch@2.0.3": version "2.0.3" resolved "https://registry.yarnpkg.com/@1inch/st1inch/-/st1inch-2.0.3.tgz#5563fa8a0d722624235f1cec8259ee8d64fd35fa" From 5661888dcd78988570e7866318b1fa2a78e48041 Mon Sep 17 00:00:00 2001 From: Mikhail Melnik Date: Wed, 1 Nov 2023 14:20:59 +0400 Subject: [PATCH 32/32] rollback order flow in tests --- test/Settlement.js | 100 +++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 54 deletions(-) diff --git a/test/Settlement.js b/test/Settlement.js index 0f7f83c1..f04ea2ae 100644 --- a/test/Settlement.js +++ b/test/Settlement.js @@ -21,38 +21,36 @@ describe('Settlement', function () { const fillOrderToData1 = await buildCalldataForOrder({ orderData: { maker: alice.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: ether('0.11'), + takingAmount: ether('100'), makerTraits: buildMakerTraits(), }, orderSigner: alice, setupData, minReturn: ether('100'), isInnermostOrder: true, - isMakingAmount: false, }); const fillOrderToData0 = await buildCalldataForOrder({ orderData: { maker: owner.address, - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.11'), - takingAmount: ether('100'), + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), makerTraits: buildMakerTraits(), }, orderSigner: owner, setupData, - minReturn: ether('0.11'), + minReturn: ether('0.1'), additionalDataForSettlement: fillOrderToData1, - isMakingAmount: false, }); const txn = await resolver.settleOrders(fillOrderToData0); - await expect(txn).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('100'), ether('-100'), ether('0')]); - await expect(txn).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('-0.11'), ether('0.1'), ether('0.01')]); + await expect(txn).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('-100'), ether('100'), ether('0')]); + await expect(txn).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('0.1'), ether('-0.11'), ether('0.01')]); }); it('settle orders with permits, permit', async function () { @@ -68,33 +66,31 @@ describe('Settlement', function () { const fillOrderToData1 = await buildCalldataForOrder({ orderData: { maker: alice.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: ether('0.11'), + takingAmount: ether('100'), makerTraits: buildMakerTraits(), }, orderSigner: alice, setupData, minReturn: ether('100'), isInnermostOrder: true, - isMakingAmount: false, }); const fillOrderToData0 = await buildCalldataForOrder({ orderData: { maker: owner.address, - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.11'), - takingAmount: ether('100'), + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), makerTraits: buildMakerTraits(), }, orderSigner: owner, setupData, - minReturn: ether('0.11'), + minReturn: ether('0.1'), additionalDataForSettlement: fillOrderToData1, - isMakingAmount: false, }); await weth.connect(alice).approve(lopv4.address, ether('0.11')); @@ -103,8 +99,8 @@ describe('Settlement', function () { const packing = (1n << 248n) | 1n; const txn = await resolver.settleOrdersWithPermits(fillOrderToData0, packing, owner.address + trim0x(dai.address) + trim0x(permit0)); - await expect(txn).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('100'), ether('-100'), ether('0')]); - await expect(txn).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('-0.11'), ether('0.1'), ether('0.01')]); + await expect(txn).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('-100'), ether('100'), ether('0')]); + await expect(txn).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('0.1'), ether('-0.11'), ether('0.01')]); }); it('settle orders with permits, permit2', async function () { @@ -120,33 +116,31 @@ describe('Settlement', function () { const fillOrderToData1 = await buildCalldataForOrder({ orderData: { maker: alice.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), - makerTraits: buildMakerTraits(), + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: ether('0.11'), + takingAmount: ether('100'), + makerTraits: buildMakerTraits({ usePermit2: true }), }, orderSigner: alice, setupData, minReturn: ether('100'), isInnermostOrder: true, - isMakingAmount: false, }); const fillOrderToData0 = await buildCalldataForOrder({ orderData: { maker: owner.address, - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.11'), - takingAmount: ether('100'), - makerTraits: buildMakerTraits(), + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), + makerTraits: buildMakerTraits({ usePermit2: true }), }, orderSigner: owner, setupData, - minReturn: ether('0.11'), + minReturn: ether('0.1'), additionalDataForSettlement: fillOrderToData1, - isMakingAmount: false, }); const permit2 = await permit2Contract(); @@ -159,8 +153,8 @@ describe('Settlement', function () { const packing = (2n << 248n) | 2n | 8n; const txn = await resolver.settleOrdersWithPermits(fillOrderToData0, packing, owner.address + trim0x(dai.address) + trim0x(permit0) + trim0x(alice.address) + trim0x(weth.address) + trim0x(permit1)); - await expect(txn).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('100'), ether('-100'), ether('0')]); - await expect(txn).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('-0.11'), ether('0.1'), ether('0.01')]); + await expect(txn).to.changeTokenBalances(dai, [owner, alice, resolver], [ether('-100'), ether('100'), ether('0')]); + await expect(txn).to.changeTokenBalances(weth, [owner, alice, resolver], [ether('0.1'), ether('-0.11'), ether('0.01')]); }); it('opposite direction recursive swap with taking fee', async function () { @@ -175,17 +169,16 @@ describe('Settlement', function () { const fillOrderToData1 = await buildCalldataForOrder({ orderData: { maker: alice.address, - makerAsset: dai.address, - takerAsset: weth.address, - makingAmount: ether('100'), - takingAmount: ether('0.1'), + makerAsset: weth.address, + takerAsset: dai.address, + makingAmount: ether('0.11'), + takingAmount: ether('100'), makerTraits: buildMakerTraits(), }, orderSigner: alice, setupData, minReturn: ether('100'), isInnermostOrder: true, - isMakingAmount: false, feeType: 2, integrator: bob.address, resolverFee: 1000000, @@ -194,17 +187,16 @@ describe('Settlement', function () { const fillOrderToData0 = await buildCalldataForOrder({ orderData: { maker: owner.address, - makerAsset: weth.address, - takerAsset: dai.address, - makingAmount: ether('0.11'), - takingAmount: ether('100'), + makerAsset: dai.address, + takerAsset: weth.address, + makingAmount: ether('100'), + takingAmount: ether('0.1'), makerTraits: buildMakerTraits(), }, orderSigner: owner, setupData, - minReturn: ether('0.11'), + minReturn: ether('0.1'), additionalDataForSettlement: fillOrderToData1, - isMakingAmount: false, feeType: 2, integrator: bob.address, resolverFee: 1000000, @@ -220,8 +212,8 @@ describe('Settlement', function () { await resolver.approve(dai.address, settlement.address); const txn = await resolver.settleOrders(fillOrderToData0); - await expect(txn).to.changeTokenBalances(dai, [owner, alice, bob], [ether('100'), ether('-100'), ether('0.1')]); - await expect(txn).to.changeTokenBalances(weth, [owner, alice, bob], [ether('-0.11'), ether('0.1'), ether('0.0001')]); + await expect(txn).to.changeTokenBalances(dai, [owner, alice, bob], [ether('-100'), ether('100'), ether('0.1')]); + await expect(txn).to.changeTokenBalances(weth, [owner, alice, bob], [ether('0.1'), ether('-0.11'), ether('0.0001')]); }); it('unidirectional recursive swap', async function () {