From b130882bfc5b9352bf59d243c4cde937f20a8e3f Mon Sep 17 00:00:00 2001 From: SRL132 Date: Thu, 5 Dec 2024 20:08:08 +0100 Subject: [PATCH 1/3] fees refactor --- contracts/src/RDEXHook.sol | 77 ++++++++++++++++++++----------- contracts/test/RDEXHookFees.t.sol | 65 ++++++++++++++++++++++++-- 2 files changed, 112 insertions(+), 30 deletions(-) diff --git a/contracts/src/RDEXHook.sol b/contracts/src/RDEXHook.sol index 27db342..85db760 100644 --- a/contracts/src/RDEXHook.sol +++ b/contracts/src/RDEXHook.sol @@ -29,10 +29,12 @@ contract RDEXHook is BaseHook, Ownable { uint24 internal immutable i_minimumFee; // discountBasisPoints is a percentage of the fee that will be discounted 1 to 1000 1 is 0.001% and 1000 is 0.1% - mapping(uint256 claimTopic => uint16 discountBasisPoints) - internal s_topicToDiscount; + // mapping(uint256 claimTopic => uint16 discountBasisPoints) + // internal s_topicToDiscount; - uint256[] internal s_topicsWithDiscount; + // uint256[] internal s_topicsWithDiscount; + + uint256 public s_reducedFeeTopic; /* ==================== EVENTS ==================== */ @@ -153,9 +155,11 @@ contract RDEXHook is BaseHook, Ownable { address _sender, PoolKey calldata, IPoolManager.SwapParams calldata, - bytes calldata + bytes calldata _hookData ) external override returns (bytes4, BeforeSwapDelta, uint24) { - uint24 fee = _calculateFee(_sender); + //ClaimData(usedIdentity, REDUCED_FEE_TOPIC, "2000");` + bool isReducedFee = abi.decode(_hookData, (bool)); + uint24 fee = isReducedFee ? _calculateFee(_sender) : 0; // poolManager.updateDynamicLPFee(_key, fee); uint24 feeWithFlag = fee | LPFeeLibrary.OVERRIDE_FEE_FLAG; @@ -195,6 +199,12 @@ contract RDEXHook is BaseHook, Ownable { emit RefCurrencyClaimTrustedIssuerSet(_refCurrencyClaimTrustedIssuer); } + // function setDynamicFee( + // uint256 _topic, + // uint16 _discountBasisPoints + // ) external onlyOwner { + // s_topicToDiscount[_topic] = _discountBasisPoints; + // } /// @notice Sets the discount basis points for a specific topic /// @dev Only the owner can call this function /// @param _topic The topic for which the discount is being set @@ -206,6 +216,14 @@ contract RDEXHook is BaseHook, Ownable { s_topicToDiscount[_topic] = _discountBasisPoints; } + // function setTopicsWithDiscount( + // uint256[] calldata _topicsWithDiscount + // ) external onlyOwner { + // s_topicsWithDiscount = _topicsWithDiscount; + // } + + function setReducedFeeTopic(uint16 _reducedFeeTopic) external onlyOwner { + s_reducedFeeTopic = _reducedFeeTopic; /// @notice Sets the topics that have discounts /// @dev Only the owner can call this function /// @param _topicsWithDiscount An array of topics that have discounts @@ -215,11 +233,18 @@ contract RDEXHook is BaseHook, Ownable { s_topicsWithDiscount = _topicsWithDiscount; } + // TODO: Explore if we need this getters or we can direclty use public variables + // function topicsWithDiscount() external view returns (uint256[] memory) { + // return s_topicsWithDiscount; + // } // TODO: Explore if we need this getters or we can directly use public variables function topicsWithDiscount() external view returns (uint256[] memory) { return s_topicsWithDiscount; } + // function dynamicFee(uint256 _topic) external view returns (uint16) { + // return s_topicToDiscount[_topic]; + // } /// @notice Returns the discount basis points for a specific topic /// @param _topic The topic for which the discount basis points are being queried /// @return The discount basis points for the specified topic @@ -286,33 +311,31 @@ contract RDEXHook is BaseHook, Ownable { function _calculateFee(address _sender) internal view returns (uint24) { //TODO: find way to let user say which topics it wants to be checked for discount during swap //TODO: find way to test that discounts actually get applied + function _calculateFee(address _sender) internal returns (uint24) { uint256 discountedFee = BASE_FEE; - uint256[] memory topicsWithDiscount = s_topicsWithDiscount; + IIdentity identity = IIdentity( s_identityRegistryStorage.storedIdentity(_sender) ); + bytes32 claimId = keccak256( + abi.encode(s_refCurrencyClaimTrustedIssuer, s_reducedFeeTopic) + ); - for (uint256 i = 0; i < topicsWithDiscount.length; i++) { - uint256 topic = topicsWithDiscount[i]; - uint256 discountBasisPoints = s_topicToDiscount[topic]; - bytes32 claimId = keccak256( - abi.encode(s_refCurrencyClaimTrustedIssuer, topic) - ); - - (, , , bytes memory sig, bytes memory data, ) = identity.getClaim( - claimId - ); - if ( - IClaimIssuer(s_refCurrencyClaimTrustedIssuer).isClaimValid( - identity, - topicsWithDiscount[i], - sig, - data - ) - ) { - unchecked { - discountedFee = discountedFee - discountBasisPoints; - } + (, , , bytes memory sig, bytes memory data, ) = identity.getClaim( + claimId + ); + if ( + IClaimIssuer(s_refCurrencyClaimTrustedIssuer).isClaimValid( + identity, + s_reducedFeeTopic, + sig, + data + ) + ) { + uint256 decodedFeeDiscount = abi.decode(data, (uint256)); + unchecked { + discountedFee = discountedFee - decodedFeeDiscount; + } if (discountedFee < i_minimumFee) { return i_minimumFee; diff --git a/contracts/test/RDEXHookFees.t.sol b/contracts/test/RDEXHookFees.t.sol index c74d042..a2b7b5d 100644 --- a/contracts/test/RDEXHookFees.t.sol +++ b/contracts/test/RDEXHookFees.t.sol @@ -20,6 +20,9 @@ import {IClaimIssuer} from "@onchain-id/solidity/contracts/interface/IClaimIssue // RDEX Hook contracts import {RDEXHook} from "src/RDEXHook.sol"; import {TREXSuite} from "./utils/TREXSuite.t.sol"; +import {PoolSwapTest} from "v4-core/src/test/PoolSwapTest.sol"; +import {IPoolManager} from "v4-core/src/interfaces/IPoolManager.sol"; +import {TickMath} from "v4-core/src/libraries/TickMath.sol"; contract MockERC20Mint is MockERC20 { function mint(address to, uint256 amount) public { @@ -70,6 +73,7 @@ contract RDEXHookFeesTest is Test, TREXSuite, Deployers { hookAddress ); hook = RDEXHook(hookAddress); + swapRouter = new PoolSwapTest(manager); // Set the identity registry storage of the Hook vm.startPrank(deployer); @@ -221,13 +225,68 @@ contract RDEXHookFeesTest is Test, TREXSuite, Deployers { ); } function test_discountTopicsGetApplied() public { + // Set up our swap parameters + PoolSwapTest.TestSettings memory testSettings = PoolSwapTest + .TestSettings({takeClaims: false, settleUsingBurn: false}); + + IPoolManager.SwapParams memory params = IPoolManager.SwapParams({ + zeroForOne: true, + amountSpecified: -0.00001 ether, + sqrtPriceLimitX96: TickMath.MIN_SQRT_PRICE + 1 + }); + uint256[] memory discountTopics = new uint256[](1); discountTopics[0] = DISCOUNT_TOPIC; vm.startPrank(deployer); - hook.setTopicsWithDiscount(discountTopics); - hook.setTopicToDiscount(DISCOUNT_TOPIC, MOCK_DISCOUNT); + // hook.setTopicsWithDiscount(discountTopics); + // hook.setDynamicFee(DISCOUNT_TOPIC, MOCK_DISCOUNT); + + // uint256 balanceOfToken1Before = currency1.balanceOfSelf(); + + // hook.swap(key, params, testSettings, ZERO_BYTES); + // uint256 balanceOfToken1After = currency1.balanceOfSelf(); + // uint256 outputFromBaseFeeSwap = balanceOfToken1After - + // balanceOfToken1Before; + + // assertGt(balanceOfToken1After, balanceOfToken1Before); + + // assertEq(outputFromBaseFeeSwap, MOCK_DISCOUNT); + + // assertEq(hook.dynamicFee(DISCOUNT_TOPIC), MOCK_DISCOUNT); + vm.stopPrank(); + + // Swap happens with discount + } + + function test_minimumFeeGetsAppliedIfDiscountTooBig() public { + // Set up our swap parameters + PoolSwapTest.TestSettings memory testSettings = PoolSwapTest + .TestSettings({takeClaims: false, settleUsingBurn: false}); + + IPoolManager.SwapParams memory params = IPoolManager.SwapParams({ + zeroForOne: true, + amountSpecified: -0.00001 ether, + sqrtPriceLimitX96: TickMath.MIN_SQRT_PRICE + 1 + }); + + uint256[] memory discountTopics = new uint256[](1); + discountTopics[0] = DISCOUNT_TOPIC; + vm.startPrank(deployer); + // hook.setTopicsWithDiscount(discountTopics); + //hook.setDynamicFee(DISCOUNT_TOPIC, 1000000); + + // uint256 balanceOfToken1Before = currency1.balanceOfSelf(); + + // hook.swap(key, params, testSettings, ZERO_BYTES); + // uint256 balanceOfToken1After = currency1.balanceOfSelf(); + // uint256 outputFromBaseFeeSwap = balanceOfToken1After - + // balanceOfToken1Before; + + // assertGt(balanceOfToken1After, balanceOfToken1Before); + + // assertEq(outputFromBaseFeeSwap, MINIMUM_FEE); - assertEq(hook.topicToDiscount(DISCOUNT_TOPIC), MOCK_DISCOUNT); + // assertEq(hook.dynamicFee(DISCOUNT_TOPIC), 1000); vm.stopPrank(); // Swap happens with discount From 9bffd51b982d280dea20548bf629a899d2efaf99 Mon Sep 17 00:00:00 2001 From: SRL132 Date: Thu, 5 Dec 2024 20:42:01 +0100 Subject: [PATCH 2/3] solve merging conflicts --- contracts/src/RDEXHook.sol | 59 +------ contracts/test/RDEXHookMarkets.t.sol | 100 ++++++++--- contracts/test/utils/TREXSuite.t.sol | 242 +++++++++++++++++++++------ 3 files changed, 264 insertions(+), 137 deletions(-) diff --git a/contracts/src/RDEXHook.sol b/contracts/src/RDEXHook.sol index 85db760..9865f69 100644 --- a/contracts/src/RDEXHook.sol +++ b/contracts/src/RDEXHook.sol @@ -199,57 +199,8 @@ contract RDEXHook is BaseHook, Ownable { emit RefCurrencyClaimTrustedIssuerSet(_refCurrencyClaimTrustedIssuer); } - // function setDynamicFee( - // uint256 _topic, - // uint16 _discountBasisPoints - // ) external onlyOwner { - // s_topicToDiscount[_topic] = _discountBasisPoints; - // } - /// @notice Sets the discount basis points for a specific topic - /// @dev Only the owner can call this function - /// @param _topic The topic for which the discount is being set - /// @param _discountBasisPoints The discount basis points to be set for the topic - function setTopicToDiscount( - uint256 _topic, - uint16 _discountBasisPoints - ) external onlyOwner { - s_topicToDiscount[_topic] = _discountBasisPoints; - } - - // function setTopicsWithDiscount( - // uint256[] calldata _topicsWithDiscount - // ) external onlyOwner { - // s_topicsWithDiscount = _topicsWithDiscount; - // } - function setReducedFeeTopic(uint16 _reducedFeeTopic) external onlyOwner { s_reducedFeeTopic = _reducedFeeTopic; - /// @notice Sets the topics that have discounts - /// @dev Only the owner can call this function - /// @param _topicsWithDiscount An array of topics that have discounts - function setTopicsWithDiscount( - uint256[] calldata _topicsWithDiscount - ) external onlyOwner { - s_topicsWithDiscount = _topicsWithDiscount; - } - - // TODO: Explore if we need this getters or we can direclty use public variables - // function topicsWithDiscount() external view returns (uint256[] memory) { - // return s_topicsWithDiscount; - // } - // TODO: Explore if we need this getters or we can directly use public variables - function topicsWithDiscount() external view returns (uint256[] memory) { - return s_topicsWithDiscount; - } - - // function dynamicFee(uint256 _topic) external view returns (uint16) { - // return s_topicToDiscount[_topic]; - // } - /// @notice Returns the discount basis points for a specific topic - /// @param _topic The topic for which the discount basis points are being queried - /// @return The discount basis points for the specified topic - function topicToDiscount(uint256 _topic) external view returns (uint16) { - return s_topicToDiscount[_topic]; } /// @notice Returns the identity registry storage @@ -309,9 +260,6 @@ contract RDEXHook is BaseHook, Ownable { /// @notice Calculates the fee /// @return The calculated fee function _calculateFee(address _sender) internal view returns (uint24) { - //TODO: find way to let user say which topics it wants to be checked for discount during swap - //TODO: find way to test that discounts actually get applied - function _calculateFee(address _sender) internal returns (uint24) { uint256 discountedFee = BASE_FEE; IIdentity identity = IIdentity( @@ -337,14 +285,11 @@ contract RDEXHook is BaseHook, Ownable { discountedFee = discountedFee - decodedFeeDiscount; } - if (discountedFee < i_minimumFee) { - return i_minimumFee; - } + if (discountedFee < i_minimumFee) { + return i_minimumFee; } } - return uint24(discountedFee); } - /* ==================== PRIVATE ==================== */ } diff --git a/contracts/test/RDEXHookMarkets.t.sol b/contracts/test/RDEXHookMarkets.t.sol index 200cfa2..b15ca99 100644 --- a/contracts/test/RDEXHookMarkets.t.sol +++ b/contracts/test/RDEXHookMarkets.t.sol @@ -35,8 +35,10 @@ contract RDEXHookMarketsTest is Test, TREXSuite, Deployers { IClaimIssuer internal refCurrencyClaimIssuerIdentity; MockERC20 internal refCurrency; IIdentity internal refCurrencyIdentity; - address internal refCurrencyIdentityAdmin = makeAddr("RefCurrencyIdentityAdmin"); - uint256 internal REF_CURRENCY_TOPIC = uint256(keccak256("REF_CURRENCY_TOPIC")); + address internal refCurrencyIdentityAdmin = + makeAddr("RefCurrencyIdentityAdmin"); + uint256 internal REF_CURRENCY_TOPIC = + uint256(keccak256("REF_CURRENCY_TOPIC")); string public REF_CURRENCY_NAME = "REF"; string public REF_CURRENCY_SYMBOL = "REF"; @@ -59,12 +61,18 @@ contract RDEXHookMarketsTest is Test, TREXSuite, Deployers { deployFreshManagerAndRouters(); /* - * RDEXHook deployment - */ + * RDEXHook deployment + */ // Deploy Hook - address hookAddress = - address((uint160(makeAddr("RDEXHook")) & ~Hooks.ALL_HOOK_MASK) | Hooks.BEFORE_INITIALIZE_FLAG); - deployCodeTo("RDEXHook.sol:RDEXHook", abi.encode(manager, deployer, 3000), hookAddress); + address hookAddress = address( + (uint160(makeAddr("RDEXHook")) & ~Hooks.ALL_HOOK_MASK) | + Hooks.BEFORE_INITIALIZE_FLAG + ); + deployCodeTo( + "RDEXHook.sol:RDEXHook", + abi.encode(manager, deployer, 3000), + hookAddress + ); hook = RDEXHook(hookAddress); // Set the identity registry storage of the Hook @@ -73,16 +81,29 @@ contract RDEXHookMarketsTest is Test, TREXSuite, Deployers { vm.stopPrank(); // Deploy ref currency claim issuer identity - (refCurrencyClaimIssuerAddr, refCurrencyClaimIssuerKey) = makeAddrAndKey("RefCurrencyClaimIssuer"); + ( + refCurrencyClaimIssuerAddr, + refCurrencyClaimIssuerKey + ) = makeAddrAndKey("RefCurrencyClaimIssuer"); vm.startPrank(refCurrencyClaimIssuerAddr); - refCurrencyClaimIssuerIdentity = - IClaimIssuer(deployArtifact("out/ClaimIssuer.sol/ClaimIssuer.json", abi.encode(refCurrencyClaimIssuerAddr))); - refCurrencyClaimIssuerIdentity.addKey(keccak256(abi.encode(refCurrencyClaimIssuerAddr)), 3, 1); + refCurrencyClaimIssuerIdentity = IClaimIssuer( + deployArtifact( + "out/ClaimIssuer.sol/ClaimIssuer.json", + abi.encode(refCurrencyClaimIssuerAddr) + ) + ); + refCurrencyClaimIssuerIdentity.addKey( + keccak256(abi.encode(refCurrencyClaimIssuerAddr)), + 3, + 1 + ); vm.stopPrank(); // Register ref currency claim issuer in the Hook vm.startPrank(deployer); - hook.setRefCurrencyClaimTrustedIssuer(address(refCurrencyClaimIssuerIdentity)); + hook.setRefCurrencyClaimTrustedIssuer( + address(refCurrencyClaimIssuerIdentity) + ); // Register ref currency claim topic in the Hook hook.setRefCurrencyClaimTopic(REF_CURRENCY_TOPIC); vm.stopPrank(); @@ -92,18 +113,31 @@ contract RDEXHookMarketsTest is Test, TREXSuite, Deployers { */ // Deploy Verified ref currency refCurrency = new MockERC20Mint(); - refCurrency.initialize(REF_CURRENCY_NAME, REF_CURRENCY_SYMBOL, DECIMALS); + refCurrency.initialize( + REF_CURRENCY_NAME, + REF_CURRENCY_SYMBOL, + DECIMALS + ); // TODO: Mint ref currency to users // Deploy ref currency identity vm.startPrank(refCurrencyIdentityAdmin); refCurrencyIdentity = IIdentity( - deployArtifact("out/IdentityProxy.sol/IdentityProxy.json", abi.encode(identityIA, refCurrencyIdentityAdmin)) + deployArtifact( + "out/IdentityProxy.sol/IdentityProxy.json", + abi.encode(identityIA, refCurrencyIdentityAdmin) + ) ); vm.stopPrank(); // Issue a claim for the ref currency identity - ClaimData memory claimForRefCurrency = - ClaimData(refCurrencyIdentity, REF_CURRENCY_TOPIC, "This is a verified stable coin by the SEC!"); - bytes memory signatureRefCurrencyClaim = signClaim(claimForRefCurrency, refCurrencyClaimIssuerKey); + ClaimData memory claimForRefCurrency = ClaimData( + refCurrencyIdentity, + REF_CURRENCY_TOPIC, + "This is a verified stable coin by the SEC!" + ); + bytes memory signatureRefCurrencyClaim = signClaim( + claimForRefCurrency, + refCurrencyClaimIssuerKey + ); //// Add claim to ref currency identity vm.startPrank(refCurrencyIdentityAdmin); refCurrencyIdentity.addClaim( @@ -117,17 +151,25 @@ contract RDEXHookMarketsTest is Test, TREXSuite, Deployers { vm.stopPrank(); // Register Identity in the identinty registry storage vm.startPrank(identityRegistryStorageAgent); - identityRegistryStorage.addIdentityToStorage(address(refCurrency), refCurrencyIdentity, COUNTRY_CODE); + identityRegistryStorage.addIdentityToStorage( + address(refCurrency), + refCurrencyIdentity, + COUNTRY_CODE + ); vm.stopPrank(); } function test_poolWithNonERC3643CompliantTokenCannotBeInitialized() public { // Deploy non compliant token MockERC20 nonCompliantToken = new MockERC20(); - nonCompliantToken.initialize(NON_COMPLIANT_TOKEN_NAME, NON_COMPLIANT_TOKEN_SYMBOL, DECIMALS); + nonCompliantToken.initialize( + NON_COMPLIANT_TOKEN_NAME, + NON_COMPLIANT_TOKEN_SYMBOL, + DECIMALS + ); Currency _currency0; Currency _currency1; - if (address(nonCompliantToken) < address(refCurrency)){ + if (address(nonCompliantToken) < address(refCurrency)) { _currency0 = Currency.wrap(address(nonCompliantToken)); _currency1 = Currency.wrap(address(refCurrency)); } else { @@ -145,13 +187,19 @@ contract RDEXHookMarketsTest is Test, TREXSuite, Deployers { ); } - function test_poolWithNonVerifiedReferenceCurrencyCannotBeInitialized() public { + function test_poolWithNonVerifiedReferenceCurrencyCannotBeInitialized() + public + { // Deploy non compliant token MockERC20 nonVerifiedRefCurrency = new MockERC20(); - nonVerifiedRefCurrency.initialize(NON_COMPLIANT_TOKEN_NAME, NON_COMPLIANT_TOKEN_SYMBOL, DECIMALS); + nonVerifiedRefCurrency.initialize( + NON_COMPLIANT_TOKEN_NAME, + NON_COMPLIANT_TOKEN_SYMBOL, + DECIMALS + ); Currency _currency0; Currency _currency1; - if (address(nonVerifiedRefCurrency) < address(TSTContracts.token)){ + if (address(nonVerifiedRefCurrency) < address(TSTContracts.token)) { _currency0 = Currency.wrap(address(nonVerifiedRefCurrency)); _currency1 = Currency.wrap(address(TSTContracts.token)); } else { @@ -169,5 +217,7 @@ contract RDEXHookMarketsTest is Test, TREXSuite, Deployers { ); } - function test_poolWithCompliantTokenAndVerifiedReferenceCurrencyCanBeInitialized() public {} -} \ No newline at end of file + function test_poolWithCompliantTokenAndVerifiedReferenceCurrencyCanBeInitialized() + public + {} +} diff --git a/contracts/test/utils/TREXSuite.t.sol b/contracts/test/utils/TREXSuite.t.sol index 4802abc..1ea65ca 100644 --- a/contracts/test/utils/TREXSuite.t.sol +++ b/contracts/test/utils/TREXSuite.t.sol @@ -24,7 +24,8 @@ import {IClaimIssuer} from "@onchain-id/solidity/contracts/interface/IClaimIssue contract TREXSuite is Test { address public deployer = makeAddr("Deployer"); // This Role Deploys the entire system and manages the agents and claim issuers - address public identityRegistryStorageAgent = makeAddr("identityRegistryStorageAgent"); // Agent in charge of register new identities directly to the storage registry + address public identityRegistryStorageAgent = + makeAddr("identityRegistryStorageAgent"); // Agent in charge of register new identities directly to the storage registry // Contracts ITREXImplementationAuthority public trexIA; @@ -33,11 +34,21 @@ contract TREXSuite is Test { IIdFactory public identityFactory; IERC3643IdentityRegistryStorage public identityRegistryStorage; - function deployArtifact(string memory artifactName, bytes memory constructorArgs) internal returns (address addr) { + function deployArtifact( + string memory artifactName, + bytes memory constructorArgs + ) internal returns (address addr) { bytes memory artifactCode = vm.getCode(artifactName); - bytes memory initializationCode = abi.encodePacked(artifactCode, constructorArgs); + bytes memory initializationCode = abi.encodePacked( + artifactCode, + constructorArgs + ); assembly { - addr := create(0, add(initializationCode, 0x20), mload(initializationCode)) + addr := create( + 0, + add(initializationCode, 0x20), + mload(initializationCode) + ) } } @@ -45,16 +56,26 @@ contract TREXSuite is Test { vm.startPrank(deployer); // Deploy TREX Implementations - address claimTopicsRegistryImplementation = - deployArtifact("out/ClaimTopicsRegistry.sol/ClaimTopicsRegistry.json", hex""); - address trustedIssuersRegistryImplementation = - deployArtifact("out/TrustedIssuersRegistry.sol/TrustedIssuersRegistry.json", hex""); - address identityRegistryStorageImplementation = - deployArtifact("out/IdentityRegistryStorage.sol/IdentityRegistryStorage.json", hex""); + address claimTopicsRegistryImplementation = deployArtifact( + "out/ClaimTopicsRegistry.sol/ClaimTopicsRegistry.json", + hex"" + ); + address trustedIssuersRegistryImplementation = deployArtifact( + "out/TrustedIssuersRegistry.sol/TrustedIssuersRegistry.json", + hex"" + ); + address identityRegistryStorageImplementation = deployArtifact( + "out/IdentityRegistryStorage.sol/IdentityRegistryStorage.json", + hex"" + ); address identityRegistryImplementation = deployArtifact( - "out/IdentityRegistry.sol/IdentityRegistry.json", abi.encode(identityRegistryStorageImplementation) + "out/IdentityRegistry.sol/IdentityRegistry.json", + abi.encode(identityRegistryStorageImplementation) + ); + address tokenImplementation = deployArtifact( + "out/Token.sol/Token.json", + hex"" ); - address tokenImplementation = deployArtifact("out/Token.sol/Token.json", hex""); // Deploy and configure TREXImplementationAutority trexIA = ITREXImplementationAuthority( @@ -77,22 +98,40 @@ contract TREXSuite is Test { // Deploy Identity Registry Storage identityRegistryStorage = IERC3643IdentityRegistryStorage( - deployArtifact("out/IdentityRegistryStorageProxy.sol/IdentityRegistryStorageProxy.json", abi.encode(trexIA)) + deployArtifact( + "out/IdentityRegistryStorageProxy.sol/IdentityRegistryStorageProxy.json", + abi.encode(trexIA) + ) + ); + IAgentRole(address(identityRegistryStorage)).addAgent( + identityRegistryStorageAgent ); - IAgentRole(address(identityRegistryStorage)).addAgent(identityRegistryStorageAgent); // Deploy ONCHAINID - address identityImplementation = deployArtifact("out/Identity.sol/Identity.json", abi.encode(deployer, true)); + address identityImplementation = deployArtifact( + "out/Identity.sol/Identity.json", + abi.encode(deployer, true) + ); identityIA = IImplementationAuthority( deployArtifact( - "out/ImplementationAuthority.sol/ImplementationAuthority.json", abi.encode(identityImplementation) + "out/ImplementationAuthority.sol/ImplementationAuthority.json", + abi.encode(identityImplementation) + ) + ); + identityFactory = IIdFactory( + deployArtifact( + "out/IdFactory.sol/IdFactory.json", + abi.encode(identityIA) ) ); - identityFactory = IIdFactory(deployArtifact("out/IdFactory.sol/IdFactory.json", abi.encode(identityIA))); // Deploy TREXFactory - trexFactory = - ITREXFactory(deployArtifact("out/TREXFactory.sol/TREXFactory.json", abi.encode(trexIA, identityFactory))); + trexFactory = ITREXFactory( + deployArtifact( + "out/TREXFactory.sol/TREXFactory.json", + abi.encode(trexIA, identityFactory) + ) + ); // Add TREXFactory as a token factory in idenitityFactory identityFactory.addTokenFactory(address(trexFactory)); @@ -130,7 +169,15 @@ contract TREXSuite is Test { function deployTSTTokenSchenario() internal { // Deploy TST token - deployToken("TEST", "TST", 18, TSTTokenIssuer, TSTTokenAgent, TSTTokenAdmin, TSTContracts); + deployToken( + "TEST", + "TST", + 18, + TSTTokenIssuer, + TSTTokenAgent, + TSTTokenAdmin, + TSTContracts + ); // Add sample claim topics vm.startPrank(deployer); @@ -142,41 +189,68 @@ contract TREXSuite is Test { // Deploy claim issuer idenitity (TSTClaimIssuerAddr, TSTClaimIssuerKey) = makeAddrAndKey("ClaimIssuer"); vm.startPrank(TSTClaimIssuerAddr); - TSTClaimIssuerIdentity = - IClaimIssuer(deployArtifact("out/ClaimIssuer.sol/ClaimIssuer.json", abi.encode(TSTClaimIssuerAddr))); - TSTClaimIssuerIdentity.addKey(keccak256(abi.encode(TSTClaimIssuerAddr)), 3, 1); + TSTClaimIssuerIdentity = IClaimIssuer( + deployArtifact( + "out/ClaimIssuer.sol/ClaimIssuer.json", + abi.encode(TSTClaimIssuerAddr) + ) + ); + TSTClaimIssuerIdentity.addKey( + keccak256(abi.encode(TSTClaimIssuerAddr)), + 3, + 1 + ); vm.stopPrank(); // Add issuer to trusted issuers registry vm.startPrank(deployer); - TSTContracts.trustedIssuersRegistry.addTrustedIssuer((TSTClaimIssuerIdentity), topics); + TSTContracts.trustedIssuersRegistry.addTrustedIssuer( + (TSTClaimIssuerIdentity), + topics + ); vm.stopPrank(); // Deploy Alice identity (aliceAddr, aliceKey) = makeAddrAndKey("Alice"); vm.startPrank(aliceAddr); - aliceIdentity = - IIdentity(deployArtifact("out/IdentityProxy.sol/IdentityProxy.json", abi.encode(identityIA, aliceAddr))); + aliceIdentity = IIdentity( + deployArtifact( + "out/IdentityProxy.sol/IdentityProxy.json", + abi.encode(identityIA, aliceAddr) + ) + ); vm.stopPrank(); // Deploy Bob identity (bobAddr, bobKey) = makeAddrAndKey("Bob"); vm.startPrank(bobAddr); - bobIdentity = - IIdentity(deployArtifact("out/IdentityProxy.sol/IdentityProxy.json", abi.encode(identityIA, bobAddr))); + bobIdentity = IIdentity( + deployArtifact( + "out/IdentityProxy.sol/IdentityProxy.json", + abi.encode(identityIA, bobAddr) + ) + ); vm.stopPrank(); // Deploy Charlie identity vm.startPrank(charlieAddr); (charlieAddr, charlieKey) = makeAddrAndKey("Charlie"); - charlieIdentity = - IIdentity(deployArtifact("out/IdentityProxy.sol/IdentityProxy.json", abi.encode(identityIA, charlieAddr))); + charlieIdentity = IIdentity( + deployArtifact( + "out/IdentityProxy.sol/IdentityProxy.json", + abi.encode(identityIA, charlieAddr) + ) + ); vm.stopPrank(); vm.startPrank(deployer); // Add new agents to the token - IAgentRole(address(TSTContracts.identityRegistry)).addAgent(address(TSTTokenAgent)); - IAgentRole(address(TSTContracts.identityRegistry)).addAgent(address(TSTContracts.token)); + IAgentRole(address(TSTContracts.identityRegistry)).addAgent( + address(TSTTokenAgent) + ); + IAgentRole(address(TSTContracts.identityRegistry)).addAgent( + address(TSTContracts.token) + ); vm.stopPrank(); vm.startPrank(TSTTokenAgent); @@ -190,24 +264,52 @@ contract TREXSuite is Test { uint16[] memory countries = new uint16[](2); countries[0] = 42; countries[1] = 666; - TSTContracts.identityRegistry.batchRegisterIdentity(addrs, identities, countries); + TSTContracts.identityRegistry.batchRegisterIdentity( + addrs, + identities, + countries + ); vm.stopPrank(); // Sign claims for alice and bob - ClaimData memory claimForAlice = ClaimData(aliceIdentity, topics[0], "Alice public data!"); - ClaimData memory claimForBob = ClaimData(bobIdentity, topics[0], "Bob public data!"); - bytes memory signatureAliceClaim = signClaim(claimForAlice, TSTClaimIssuerKey); - bytes memory signatureBobClaim = signClaim(claimForBob, TSTClaimIssuerKey); + ClaimData memory claimForAlice = ClaimData( + aliceIdentity, + topics[0], + "Alice public data!" + ); + ClaimData memory claimForBob = ClaimData( + bobIdentity, + topics[0], + "Bob public data!" + ); + bytes memory signatureAliceClaim = signClaim( + claimForAlice, + TSTClaimIssuerKey + ); + bytes memory signatureBobClaim = signClaim( + claimForBob, + TSTClaimIssuerKey + ); // Add claims to Alice and Bob identities vm.startPrank(aliceAddr); aliceIdentity.addClaim( - claimForAlice.topic, 1, address(TSTClaimIssuerIdentity), signatureAliceClaim, claimForAlice.data, "" + claimForAlice.topic, + 1, + address(TSTClaimIssuerIdentity), + signatureAliceClaim, + claimForAlice.data, + "" ); vm.stopPrank(); vm.startPrank(bobAddr); bobIdentity.addClaim( - claimForBob.topic, 1, address(TSTClaimIssuerIdentity), signatureBobClaim, claimForBob.data, "" + claimForBob.topic, + 1, + address(TSTClaimIssuerIdentity), + signatureBobClaim, + claimForBob.data, + "" ); vm.stopPrank(); @@ -219,12 +321,17 @@ contract TREXSuite is Test { // Final Agent configuration vm.startPrank(TSTTokenAgent); - (bool success,) = - TSTContracts.agentManager.call(abi.encodeWithSignature("addAgentAdmin(address)", TSTTokenAdmin)); + (bool success, ) = TSTContracts.agentManager.call( + abi.encodeWithSignature("addAgentAdmin(address)", TSTTokenAdmin) + ); vm.stopPrank(); vm.startPrank(deployer); - IAgentRole(address(TSTContracts.token)).addAgent(TSTContracts.agentManager); - IAgentRole(address(TSTContracts.identityRegistry)).addAgent(TSTContracts.agentManager); + IAgentRole(address(TSTContracts.token)).addAgent( + TSTContracts.agentManager + ); + IAgentRole(address(TSTContracts.identityRegistry)).addAgent( + TSTContracts.agentManager + ); vm.stopPrank(); vm.startPrank(TSTTokenAgent); TSTContracts.token.unpause(); @@ -237,9 +344,16 @@ contract TREXSuite is Test { bytes data; } - function signClaim(ClaimData memory claim, uint256 privateKey) internal returns (bytes memory signature) { - bytes32 dataHash = keccak256(abi.encode(claim.identity, claim.topic, claim.data)); - bytes32 prefixedHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", dataHash)); + function signClaim( + ClaimData memory claim, + uint256 privateKey + ) internal returns (bytes memory signature) { + bytes32 dataHash = keccak256( + abi.encode(claim.identity, claim.topic, claim.data) + ); + bytes32 prefixedHash = keccak256( + abi.encodePacked("\x19Ethereum Signed Message:\n32", dataHash) + ); (uint8 v, bytes32 r, bytes32 s) = vm.sign(privateKey, prefixedHash); signature = abi.encodePacked(r, s, v); @@ -269,18 +383,32 @@ contract TREXSuite is Test { ) internal { vm.startPrank(deployer); // Deploy token ONCHAINID - tokenContracts.identity = - IIdentity(deployArtifact("out/IdentityProxy.sol/IdentityProxy.json", abi.encode(identityIA, tokenIssuer))); + tokenContracts.identity = IIdentity( + deployArtifact( + "out/IdentityProxy.sol/IdentityProxy.json", + abi.encode(identityIA, tokenIssuer) + ) + ); // Deploy token contracts tokenContracts.claimTopicsRegistry = IERC3643ClaimTopicsRegistry( - deployArtifact("out/ClaimTopicsRegistryProxy.sol/ClaimTopicsRegistryProxy.json", abi.encode(trexIA)) + deployArtifact( + "out/ClaimTopicsRegistryProxy.sol/ClaimTopicsRegistryProxy.json", + abi.encode(trexIA) + ) ); tokenContracts.trustedIssuersRegistry = IERC3643TrustedIssuersRegistry( - deployArtifact("out/TrustedIssuersRegistryProxy.sol/TrustedIssuersRegistryProxy.json", abi.encode(trexIA)) + deployArtifact( + "out/TrustedIssuersRegistryProxy.sol/TrustedIssuersRegistryProxy.json", + abi.encode(trexIA) + ) ); - tokenContracts.compliance = - IERC3643Compliance(deployArtifact("out/DefaultCompliance.sol/DefaultCompliance.json", hex"")); // Mock compliance canTransfer always true + tokenContracts.compliance = IERC3643Compliance( + deployArtifact( + "out/DefaultCompliance.sol/DefaultCompliance.json", + hex"" + ) + ); // Mock compliance canTransfer always true tokenContracts.identityRegistry = IERC3643IdentityRegistry( deployArtifact( "out/IdentityRegistryProxy.sol/IdentityRegistryProxy.json", @@ -310,13 +438,17 @@ contract TREXSuite is Test { // Deploy AgentManager vm.startPrank(tokenAgent); - tokenContracts.agentManager = - deployArtifact("out/AgentManager.sol/AgentManager.json", abi.encode(tokenContracts.token)); + tokenContracts.agentManager = deployArtifact( + "out/AgentManager.sol/AgentManager.json", + abi.encode(tokenContracts.token) + ); vm.stopPrank(); vm.startPrank(deployer); // Bind Identity registry to token - identityRegistryStorage.bindIdentityRegistry(address(tokenContracts.identityRegistry)); + identityRegistryStorage.bindIdentityRegistry( + address(tokenContracts.identityRegistry) + ); // Add Agent to the token IAgentRole(address(tokenContracts.token)).addAgent(tokenAgent); From 53f8fb96daf0aeb19d9b6db2e4d4b1d112436b43 Mon Sep 17 00:00:00 2001 From: SRL132 Date: Thu, 5 Dec 2024 20:47:17 +0100 Subject: [PATCH 3/3] add before swap flag --- contracts/test/RDEXHookFees.t.sol | 3 ++- contracts/test/RDEXHookMarkets.t.sol | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/contracts/test/RDEXHookFees.t.sol b/contracts/test/RDEXHookFees.t.sol index a2b7b5d..47c80f4 100644 --- a/contracts/test/RDEXHookFees.t.sol +++ b/contracts/test/RDEXHookFees.t.sol @@ -65,7 +65,8 @@ contract RDEXHookFeesTest is Test, TREXSuite, Deployers { // Deploy Hook address hookAddress = address( (uint160(makeAddr("RDEXHook")) & ~Hooks.ALL_HOOK_MASK) | - Hooks.BEFORE_INITIALIZE_FLAG + Hooks.BEFORE_INITIALIZE_FLAG | + Hooks.BEFORE_SWAP_FLAG ); deployCodeTo( "RDEXHook.sol:RDEXHook", diff --git a/contracts/test/RDEXHookMarkets.t.sol b/contracts/test/RDEXHookMarkets.t.sol index b15ca99..300709c 100644 --- a/contracts/test/RDEXHookMarkets.t.sol +++ b/contracts/test/RDEXHookMarkets.t.sol @@ -66,7 +66,8 @@ contract RDEXHookMarketsTest is Test, TREXSuite, Deployers { // Deploy Hook address hookAddress = address( (uint160(makeAddr("RDEXHook")) & ~Hooks.ALL_HOOK_MASK) | - Hooks.BEFORE_INITIALIZE_FLAG + Hooks.BEFORE_INITIALIZE_FLAG | + Hooks.BEFORE_SWAP_FLAG ); deployCodeTo( "RDEXHook.sol:RDEXHook",