From 9c2a36bca8521c37e018d016b080ac73de510620 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Mon, 1 Jul 2024 11:26:51 +0400 Subject: [PATCH 01/12] Test testReceiptTransfer with Owner being a handler --- .../OffchainAssetReceiptVault.handler.t.sol | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol new file mode 100644 index 00000000..472522e6 --- /dev/null +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: CAL +pragma solidity =0.8.25; + +import { + OffchainAssetReceiptVault, + OffchainAssetReceiptVaultConfig +} from "../../../../../contracts/concrete/vault/OffchainAssetReceiptVault.sol"; +import {OffchainAssetReceiptVaultTest, Vm} from "test/foundry/abstract/OffchainAssetReceiptVaultTest.sol"; +import {LibOffchainAssetVaultCreator} from "test/foundry/lib/LibOffchainAssetVaultCreator.sol"; +import {Receipt as ReceiptContract} from "../../../../../contracts/concrete/receipt/Receipt.sol"; + +contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { + event SetERC20Tier(address sender, address tier, uint256 minimumTier, uint256[] context, bytes data); + event SetERC1155Tier(address sender, address tier, uint256 minimumTier, uint256[] context, bytes data); + event OffchainAssetReceiptVaultInitialized(address sender, OffchainAssetReceiptVaultConfig config); + event DepositWithReceipt( + address sender, address owner, uint256 assets, uint256 shares, uint256 id, bytes receiptInformation + ); + + /// Get Receipt from event + function getReceipt() internal returns (ReceiptContract) { + Vm.Log[] memory logs = vm.getRecordedLogs(); + + // Find the OffchainAssetReceiptVaultInitialized event log + address receiptAddress = address(0); + bool eventFound = false; // Flag to indicate whether the event log was found + for (uint256 i = 0; i < logs.length; i++) { + if (logs[i].topics[0] == OffchainAssetReceiptVaultInitialized.selector) { + // Decode the event data + (, OffchainAssetReceiptVaultConfig memory config) = + abi.decode(logs[i].data, (address, OffchainAssetReceiptVaultConfig)); + receiptAddress = config.receiptVaultConfig.receipt; + eventFound = true; // Set the flag to true since event log was found + break; + } + } + + // Assert that the event log was found + assertTrue(eventFound, "OffchainAssetReceiptVaultInitialized event log not found"); + // Return an receipt contract + return ReceiptContract(receiptAddress); + } + + /// Test testReceiptTransfer with Owner being a handler + function testReceiptTransferHandlerOwner( + uint256 fuzzedKeyAlice, + uint256 fuzzedKeyBob, + uint256 fuzzedKeyJohn, + string memory assetName, + uint256 referenceBlockNumber, + uint256 certifyUntil, + uint256 futureTimeStamp, + bool forceUntil + ) external { + // Ensure the fuzzed key is within the valid range for secp256k1 + address alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1); + address bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); + address john = vm.addr((fuzzedKeyJohn % (SECP256K1_ORDER - 1)) + 1); + + referenceBlockNumber = bound(referenceBlockNumber, 1, block.number); + certifyUntil = bound(certifyUntil, 1, type(uint32).max - 1); // substruct 1 for next bound + + // Need setting future timestamp so system gets unsertified but transfer is possible + // due to a handler role + futureTimeStamp = bound(futureTimeStamp, certifyUntil + 1, type(uint32).max); + + vm.assume(alice != bob); + vm.assume(alice != john); + vm.assume(bob != john); + + // Start recording logs + vm.recordLogs(); + OffchainAssetReceiptVault vault = createVault(alice, assetName, assetName); + ReceiptContract receipt = getReceipt(); + + // Prank as Alice to grant roles + vm.startPrank(alice); + + vault.grantRole(vault.CERTIFIER(), alice); + vault.grantRole(vault.HANDLER(), bob); + vault.grantRole(vault.DEPOSITOR(), alice); + + // Call the certify function + vault.certify(certifyUntil, referenceBlockNumber, forceUntil, bytes("")); + + // Cannot fuzz assets value due to variable limits + vault.deposit(100, bob, 1, bytes("")); + + vm.stopPrank(); + vm.warp(certifyUntil); + + // Prank as Bob + vm.startPrank(bob); + vault.authorizeReceiptTransfer(bob, john); + receipt.safeTransferFrom(bob, john, 1, 10, bytes("")); + assertEq(receipt.balanceOf(john, 1), 10); + + vm.stopPrank(); + } +} From 0bd554591e5084625d8fd37fa324824bdebfe5b5 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Mon, 1 Jul 2024 11:33:12 +0400 Subject: [PATCH 02/12] Test testReceiptTransfer with Receiver being a handler --- .../OffchainAssetReceiptVault.handler.t.sol | 71 +++++++++++++++++-- 1 file changed, 66 insertions(+), 5 deletions(-) diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol index 472522e6..da3dce48 100644 --- a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol @@ -50,13 +50,15 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { uint256 referenceBlockNumber, uint256 certifyUntil, uint256 futureTimeStamp, - bool forceUntil + bool forceUntil, + uint256 balance ) external { // Ensure the fuzzed key is within the valid range for secp256k1 address alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1); address bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); address john = vm.addr((fuzzedKeyJohn % (SECP256K1_ORDER - 1)) + 1); + balance = bound(balance, 1, type(uint256).max); // Bound from one to avoid ZeroAssets referenceBlockNumber = bound(referenceBlockNumber, 1, block.number); certifyUntil = bound(certifyUntil, 1, type(uint32).max - 1); // substruct 1 for next bound @@ -84,16 +86,75 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { vault.certify(certifyUntil, referenceBlockNumber, forceUntil, bytes("")); // Cannot fuzz assets value due to variable limits - vault.deposit(100, bob, 1, bytes("")); + vault.deposit(balance, bob, 1, bytes("")); vm.stopPrank(); - vm.warp(certifyUntil); + vm.warp(futureTimeStamp); // Prank as Bob vm.startPrank(bob); vault.authorizeReceiptTransfer(bob, john); - receipt.safeTransferFrom(bob, john, 1, 10, bytes("")); - assertEq(receipt.balanceOf(john, 1), 10); + receipt.safeTransferFrom(bob, john, 1, balance, bytes("")); + assertEq(receipt.balanceOf(john, 1), balance); + + vm.stopPrank(); + } + + /// Test testReceiptTransfer with Receiver being a handler + function testReceiptTransferHandlerReceiver( + uint256 fuzzedKeyAlice, + uint256 fuzzedKeyBob, + uint256 fuzzedKeyJohn, + string memory assetName, + uint256 referenceBlockNumber, + uint256 certifyUntil, + uint256 futureTimeStamp, + bool forceUntil, + uint256 balance + ) external { + // Ensure the fuzzed key is within the valid range for secp256k1 + address alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1); + address bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); + address john = vm.addr((fuzzedKeyJohn % (SECP256K1_ORDER - 1)) + 1); + + balance = bound(balance, 1, type(uint256).max); // Bound from one to avoid ZeroAssets + referenceBlockNumber = bound(referenceBlockNumber, 1, block.number); + certifyUntil = bound(certifyUntil, 1, type(uint32).max - 1); // substruct 1 for next bound + + // Need setting future timestamp so system gets unsertified but transfer is possible + // due to a handler role + futureTimeStamp = bound(futureTimeStamp, certifyUntil + 1, type(uint32).max); + + vm.assume(alice != bob); + vm.assume(alice != john); + vm.assume(bob != john); + + // Start recording logs + vm.recordLogs(); + OffchainAssetReceiptVault vault = createVault(alice, assetName, assetName); + ReceiptContract receipt = getReceipt(); + + // Prank as Alice to grant roles + vm.startPrank(alice); + + vault.grantRole(vault.CERTIFIER(), alice); + vault.grantRole(vault.HANDLER(), john); + vault.grantRole(vault.DEPOSITOR(), alice); + + // Call the certify function + vault.certify(certifyUntil, referenceBlockNumber, forceUntil, bytes("")); + + // Cannot fuzz assets value due to variable limits + vault.deposit(balance, bob, 1, bytes("")); + + vm.stopPrank(); + vm.warp(futureTimeStamp); + + // Prank as Bob + vm.startPrank(bob); + vault.authorizeReceiptTransfer(bob, john); + receipt.safeTransferFrom(bob, john, 1, balance, bytes("")); + assertEq(receipt.balanceOf(john, 1), balance); vm.stopPrank(); } From 4ab6c7db2f3a67bdde6cc93d5f063a25370ceb09 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Mon, 1 Jul 2024 11:36:59 +0400 Subject: [PATCH 03/12] Test testReceiptTransfer to self with handler role --- .../OffchainAssetReceiptVault.handler.t.sol | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol index da3dce48..72c2bb12 100644 --- a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol @@ -41,6 +41,61 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { return ReceiptContract(receiptAddress); } + /// Test testReceiptTransfer to self with handler role + function testReceiptTransferHandler( + uint256 fuzzedKeyAlice, + uint256 fuzzedKeyBob, + string memory assetName, + uint256 referenceBlockNumber, + uint256 certifyUntil, + uint256 futureTimeStamp, + bool forceUntil, + uint256 balance + ) external { + // Ensure the fuzzed key is within the valid range for secp256k1 + address alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1); + address bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); + + balance = bound(balance, 1, type(uint256).max); // Bound from one to avoid ZeroAssets + referenceBlockNumber = bound(referenceBlockNumber, 1, block.number); + certifyUntil = bound(certifyUntil, 1, type(uint32).max - 1); // substruct 1 for next bound + + // Need setting future timestamp so system gets unsertified but transfer is possible + // due to a handler role + futureTimeStamp = bound(futureTimeStamp, certifyUntil + 1, type(uint32).max); + + vm.assume(alice != bob); + + // Start recording logs + vm.recordLogs(); + OffchainAssetReceiptVault vault = createVault(alice, assetName, assetName); + ReceiptContract receipt = getReceipt(); + + // Prank as Alice to grant roles + vm.startPrank(alice); + + vault.grantRole(vault.CERTIFIER(), alice); + vault.grantRole(vault.HANDLER(), bob); + vault.grantRole(vault.DEPOSITOR(), alice); + + // Call the certify function + vault.certify(certifyUntil, referenceBlockNumber, forceUntil, bytes("")); + + // Cannot fuzz assets value due to variable limits + vault.deposit(balance, bob, 1, bytes("")); + + vm.stopPrank(); + vm.warp(futureTimeStamp); + + // Prank as Bob + vm.startPrank(bob); + vault.authorizeReceiptTransfer(bob, bob); + receipt.safeTransferFrom(bob, bob, 1, balance, bytes("")); + assertEq(receipt.balanceOf(bob, 1), balance); + + vm.stopPrank(); + } + /// Test testReceiptTransfer with Owner being a handler function testReceiptTransferHandlerOwner( uint256 fuzzedKeyAlice, From f56400be97c35bf24087b4bbea15f14a1025c906 Mon Sep 17 00:00:00 2001 From: David Meister Date: Mon, 1 Jul 2024 13:46:06 +0400 Subject: [PATCH 04/12] Update test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol --- .../src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol index 72c2bb12..b630d241 100644 --- a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol @@ -176,7 +176,7 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { referenceBlockNumber = bound(referenceBlockNumber, 1, block.number); certifyUntil = bound(certifyUntil, 1, type(uint32).max - 1); // substruct 1 for next bound - // Need setting future timestamp so system gets unsertified but transfer is possible + // Need setting future timestamp so system gets uncertified but transfer is possible // due to a handler role futureTimeStamp = bound(futureTimeStamp, certifyUntil + 1, type(uint32).max); From 3418f67ca0f0ad1ab0cff79edc12710e2d32859c Mon Sep 17 00:00:00 2001 From: David Meister Date: Mon, 1 Jul 2024 13:46:42 +0400 Subject: [PATCH 05/12] Update test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol --- .../src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol index b630d241..d03d4cd6 100644 --- a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol @@ -117,7 +117,7 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { referenceBlockNumber = bound(referenceBlockNumber, 1, block.number); certifyUntil = bound(certifyUntil, 1, type(uint32).max - 1); // substruct 1 for next bound - // Need setting future timestamp so system gets unsertified but transfer is possible + // Need setting future timestamp so system gets uncertified but transfer is possible // due to a handler role futureTimeStamp = bound(futureTimeStamp, certifyUntil + 1, type(uint32).max); From 273e974e688344f608a0afae078d3496ebab9683 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Mon, 1 Jul 2024 17:40:18 +0400 Subject: [PATCH 06/12] Move getReceipt function under contract and update handler test --- .../OffchainAssetReceiptVaultTest.sol | 21 ++++++++++ .../OffchainAssetReceiptVault.handler.t.sol | 42 +++++-------------- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol b/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol index 104706d6..6992b655 100644 --- a/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol +++ b/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol @@ -5,6 +5,7 @@ import {Test, Vm} from "forge-std/Test.sol"; import {ICloneableFactoryV2} from "rain.factory/interface/ICloneableFactoryV2.sol"; import {CloneFactory} from "rain.factory/concrete/CloneFactory.sol"; import { + OffchainAssetReceiptVaultConfig, OffchainAssetReceiptVault, ReceiptVaultConstructionConfig } from "contracts/concrete/vault/OffchainAssetReceiptVault.sol"; @@ -12,6 +13,8 @@ import {LibOffchainAssetVaultCreator} from "../lib/LibOffchainAssetVaultCreator. import {Receipt as ReceiptContract} from "contracts/concrete/receipt/Receipt.sol"; contract OffchainAssetReceiptVaultTest is Test { + event OffchainAssetReceiptVaultInitialized(address sender, OffchainAssetReceiptVaultConfig config); + ICloneableFactoryV2 internal immutable iFactory; OffchainAssetReceiptVault internal immutable iImplementation; ReceiptContract internal immutable receiptImplementation; @@ -30,4 +33,22 @@ contract OffchainAssetReceiptVaultTest is Test { { return LibOffchainAssetVaultCreator.createVault(iFactory, iImplementation, admin, name, symbol); } + + function getReceipt(Vm.Log[] memory logs) internal pureeturns(ReceiptContract) { + // Find the OffchainAssetReceiptVaultInitialized event log + address receiptAddress = address(0); + bool eventFound = false; // Flag to indicate whether the event log was found + for (uint256 i = 0; i < logs.length; i++) { + if (logs[i].topics[0] == OffchainAssetReceiptVaultInitialized.selector) { + // Decode the event data + (, OffchainAssetReceiptVaultConfig memory config) = + abi.decode(logs[i].data, (address, OffchainAssetReceiptVaultConfig)); + receiptAddress = config.receiptVaultConfig.receipt; + eventFound = true; // Set the flag to true since event log was found + break; + } + } + // Return an receipt contract + return ReceiptContract(receiptAddress); + } } diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol index 72c2bb12..d0d25e0e 100644 --- a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol @@ -1,10 +1,7 @@ // SPDX-License-Identifier: CAL pragma solidity =0.8.25; -import { - OffchainAssetReceiptVault, - OffchainAssetReceiptVaultConfig -} from "../../../../../contracts/concrete/vault/OffchainAssetReceiptVault.sol"; +import {OffchainAssetReceiptVault} from "../../../../../contracts/concrete/vault/OffchainAssetReceiptVault.sol"; import {OffchainAssetReceiptVaultTest, Vm} from "test/foundry/abstract/OffchainAssetReceiptVaultTest.sol"; import {LibOffchainAssetVaultCreator} from "test/foundry/lib/LibOffchainAssetVaultCreator.sol"; import {Receipt as ReceiptContract} from "../../../../../contracts/concrete/receipt/Receipt.sol"; @@ -12,35 +9,10 @@ import {Receipt as ReceiptContract} from "../../../../../contracts/concrete/rece contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { event SetERC20Tier(address sender, address tier, uint256 minimumTier, uint256[] context, bytes data); event SetERC1155Tier(address sender, address tier, uint256 minimumTier, uint256[] context, bytes data); - event OffchainAssetReceiptVaultInitialized(address sender, OffchainAssetReceiptVaultConfig config); event DepositWithReceipt( address sender, address owner, uint256 assets, uint256 shares, uint256 id, bytes receiptInformation ); - /// Get Receipt from event - function getReceipt() internal returns (ReceiptContract) { - Vm.Log[] memory logs = vm.getRecordedLogs(); - - // Find the OffchainAssetReceiptVaultInitialized event log - address receiptAddress = address(0); - bool eventFound = false; // Flag to indicate whether the event log was found - for (uint256 i = 0; i < logs.length; i++) { - if (logs[i].topics[0] == OffchainAssetReceiptVaultInitialized.selector) { - // Decode the event data - (, OffchainAssetReceiptVaultConfig memory config) = - abi.decode(logs[i].data, (address, OffchainAssetReceiptVaultConfig)); - receiptAddress = config.receiptVaultConfig.receipt; - eventFound = true; // Set the flag to true since event log was found - break; - } - } - - // Assert that the event log was found - assertTrue(eventFound, "OffchainAssetReceiptVaultInitialized event log not found"); - // Return an receipt contract - return ReceiptContract(receiptAddress); - } - /// Test testReceiptTransfer to self with handler role function testReceiptTransferHandler( uint256 fuzzedKeyAlice, @@ -69,7 +41,9 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { // Start recording logs vm.recordLogs(); OffchainAssetReceiptVault vault = createVault(alice, assetName, assetName); - ReceiptContract receipt = getReceipt(); + Vm.Log[] memory logs = vm.getRecordedLogs(); + + ReceiptContract receipt = getReceipt(logs); // Prank as Alice to grant roles vm.startPrank(alice); @@ -128,7 +102,9 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { // Start recording logs vm.recordLogs(); OffchainAssetReceiptVault vault = createVault(alice, assetName, assetName); - ReceiptContract receipt = getReceipt(); + Vm.Log[] memory logs = vm.getRecordedLogs(); + + ReceiptContract receipt = getReceipt(logs); // Prank as Alice to grant roles vm.startPrank(alice); @@ -187,7 +163,9 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { // Start recording logs vm.recordLogs(); OffchainAssetReceiptVault vault = createVault(alice, assetName, assetName); - ReceiptContract receipt = getReceipt(); + Vm.Log[] memory logs = vm.getRecordedLogs(); + + ReceiptContract receipt = getReceipt(logs); // Prank as Alice to grant roles vm.startPrank(alice); From 7dc9f3364d26c35622654333b6827eb7900fcd12 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Mon, 1 Jul 2024 17:45:19 +0400 Subject: [PATCH 07/12] Merging issue fix --- test/foundry/abstract/OffchainAssetReceiptVaultTest.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol b/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol index 6992b655..a3941f75 100644 --- a/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol +++ b/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol @@ -34,7 +34,7 @@ contract OffchainAssetReceiptVaultTest is Test { return LibOffchainAssetVaultCreator.createVault(iFactory, iImplementation, admin, name, symbol); } - function getReceipt(Vm.Log[] memory logs) internal pureeturns(ReceiptContract) { + function getReceipt(Vm.Log[] memory logs) internal pure returns(ReceiptContract) { // Find the OffchainAssetReceiptVaultInitialized event log address receiptAddress = address(0); bool eventFound = false; // Flag to indicate whether the event log was found From e5e72873b6c012aa2a66f2c62eb0031ae092a1c7 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Mon, 1 Jul 2024 17:45:38 +0400 Subject: [PATCH 08/12] fmt --- test/foundry/abstract/OffchainAssetReceiptVaultTest.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol b/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol index a3941f75..616427f7 100644 --- a/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol +++ b/test/foundry/abstract/OffchainAssetReceiptVaultTest.sol @@ -34,7 +34,7 @@ contract OffchainAssetReceiptVaultTest is Test { return LibOffchainAssetVaultCreator.createVault(iFactory, iImplementation, admin, name, symbol); } - function getReceipt(Vm.Log[] memory logs) internal pure returns(ReceiptContract) { + function getReceipt(Vm.Log[] memory logs) internal pure returns (ReceiptContract) { // Find the OffchainAssetReceiptVaultInitialized event log address receiptAddress = address(0); bool eventFound = false; // Flag to indicate whether the event log was found From 70ac08bb5d0a3903ee07f85423ed3953fe01122b Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Mon, 1 Jul 2024 17:59:53 +0400 Subject: [PATCH 09/12] Use contract getReceipt in all tests. Remove extra declarations and imports --- ...nAssetReceiptVault.confiscateReceipt.t.sol | 36 ++++--------------- ...inAssetReceiptVault.confiscateShares.t.sol | 1 - .../OffchainAssetReceiptVault.tiers.t.sol | 29 ++------------- 3 files changed, 9 insertions(+), 57 deletions(-) diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.confiscateReceipt.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.confiscateReceipt.t.sol index e1a67607..7760a650 100644 --- a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.confiscateReceipt.t.sol +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.confiscateReceipt.t.sol @@ -10,31 +10,6 @@ import {Receipt as ReceiptContract} from "../../../../../contracts/concrete/rece contract ConfiscateReceiptTest is OffchainAssetReceiptVaultTest { event ConfiscateReceipt(address sender, address confiscatee, uint256 id, uint256 confiscated, bytes justification); - event OffchainAssetReceiptVaultInitialized(address sender, OffchainAssetReceiptVaultConfig config); - - /// Get Receipt from event - function getReceipt() internal returns (ReceiptContract) { - Vm.Log[] memory logs = vm.getRecordedLogs(); - - // Find the OffchainAssetReceiptVaultInitialized event log - address receiptAddress = address(0); - bool eventFound = false; // Flag to indicate whether the event log was found - for (uint256 i = 0; i < logs.length; i++) { - if (logs[i].topics[0] == OffchainAssetReceiptVaultInitialized.selector) { - // Decode the event data - (, OffchainAssetReceiptVaultConfig memory config) = - abi.decode(logs[i].data, (address, OffchainAssetReceiptVaultConfig)); - receiptAddress = config.receiptVaultConfig.receipt; - eventFound = true; // Set the flag to true since event log was found - break; - } - } - - // Assert that the event log was found - assertTrue(eventFound, "OffchainAssetReceiptVaultInitialized event log not found"); - // Return an receipt contract - return ReceiptContract(receiptAddress); - } /// Checks that confiscateReceipt balances don't change or do change as expected function checkConfiscateReceipt( @@ -91,7 +66,9 @@ contract ConfiscateReceiptTest is OffchainAssetReceiptVaultTest { // Start recording logs vm.recordLogs(); OffchainAssetReceiptVault vault = createVault(alice, assetName, assetSymbol); - ReceiptContract receipt = getReceipt(); + Vm.Log[] memory logs = vm.getRecordedLogs(); + ReceiptContract receipt = getReceipt(logs); + // Prank as Alice to grant role vm.startPrank(alice); @@ -117,6 +94,7 @@ contract ConfiscateReceiptTest is OffchainAssetReceiptVaultTest { // Ensure the fuzzed key is within the valid range for secp256k1 address alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1); address bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); + vm.assume(alice != bob); blockNumber = bound(blockNumber, 0, type(uint256).max); vm.roll(blockNumber); @@ -126,11 +104,11 @@ contract ConfiscateReceiptTest is OffchainAssetReceiptVaultTest { // Assume that assets is less than uint256 max assets = bound(assets, 1, type(uint256).max); + // Start recording logs vm.recordLogs(); OffchainAssetReceiptVault vault = createVault(alice, assetName, assetName); - ReceiptContract receipt = getReceipt(); - vm.assume(alice != bob); + Vm.Log[] memory logs = vm.getRecordedLogs(); // Prank as Alice to set roles vm.startPrank(alice); @@ -146,7 +124,7 @@ contract ConfiscateReceiptTest is OffchainAssetReceiptVaultTest { vault.deposit(assets, alice, minShareRatio, data); - checkConfiscateReceipt(vault, receipt, alice, bob, 1, data); + checkConfiscateReceipt(vault, getReceipt(logs), alice, bob, 1, data); vm.stopPrank(); } } diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.confiscateShares.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.confiscateShares.t.sol index 08b66e95..63f7b9ce 100644 --- a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.confiscateShares.t.sol +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.confiscateShares.t.sol @@ -10,7 +10,6 @@ import {Receipt as ReceiptContract} from "../../../../../contracts/concrete/rece contract ConfiscateSharesTest is OffchainAssetReceiptVaultTest { event ConfiscateShares(address sender, address confiscatee, uint256 confiscated, bytes justification); - event OffchainAssetReceiptVaultInitialized(address sender, OffchainAssetReceiptVaultConfig config); /// Checks that confiscateShares balances don't change or do change as expected function checkConfiscateShares(OffchainAssetReceiptVault vault, address alice, address bob, bytes memory data) diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.tiers.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.tiers.t.sol index 902b7e27..ba8ca3eb 100644 --- a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.tiers.t.sol +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.tiers.t.sol @@ -10,36 +10,10 @@ import {OffchainAssetReceiptVaultTest, Vm} from "test/foundry/abstract/OffchainA import {LibOffchainAssetVaultCreator} from "test/foundry/lib/LibOffchainAssetVaultCreator.sol"; import {ITierV2} from "rain.tier.interface/interface/ITierV2.sol"; import {Receipt as ReceiptContract} from "../../../../../contracts/concrete/receipt/Receipt.sol"; -import "forge-std/console.sol"; contract TiersTest is OffchainAssetReceiptVaultTest { event SetERC20Tier(address sender, address tier, uint256 minimumTier, uint256[] context, bytes data); event SetERC1155Tier(address sender, address tier, uint256 minimumTier, uint256[] context, bytes data); - event OffchainAssetReceiptVaultInitialized(address sender, OffchainAssetReceiptVaultConfig config); - - /// Get Receipt from event - function getReceipt() internal returns (ReceiptContract) { - Vm.Log[] memory logs = vm.getRecordedLogs(); - - // Find the OffchainAssetReceiptVaultInitialized event log - address receiptAddress = address(0); - bool eventFound = false; // Flag to indicate whether the event log was found - for (uint256 i = 0; i < logs.length; i++) { - if (logs[i].topics[0] == OffchainAssetReceiptVaultInitialized.selector) { - // Decode the event data - (, OffchainAssetReceiptVaultConfig memory config) = - abi.decode(logs[i].data, (address, OffchainAssetReceiptVaultConfig)); - receiptAddress = config.receiptVaultConfig.receipt; - eventFound = true; // Set the flag to true since event log was found - break; - } - } - - // Assert that the event log was found - assertTrue(eventFound, "OffchainAssetReceiptVaultInitialized event log not found"); - // Return an receipt contract - return ReceiptContract(receiptAddress); - } /// Test setERC20Tier event function testSetERC20Tier( @@ -391,7 +365,7 @@ contract TiersTest is OffchainAssetReceiptVaultTest { // Start recording logs vm.recordLogs(); OffchainAssetReceiptVault vault = createVault(alice, assetName, assetName); - ReceiptContract receipt = getReceipt(); + Vm.Log[] memory logs = vm.getRecordedLogs(); // Prank as Alice to grant roles vm.startPrank(alice); @@ -423,6 +397,7 @@ contract TiersTest is OffchainAssetReceiptVaultTest { ); vault.authorizeReceiptTransfer(bob, alice); + ReceiptContract receipt = getReceipt(logs); receipt.safeTransferFrom(bob, alice, 1, 10, bytes("")); assertEq(receipt.balanceOf(alice, 1), 10); From 918e3be6fc6a2c225118d5ca613b30a61b34eacb Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Tue, 2 Jul 2024 10:39:45 +0400 Subject: [PATCH 10/12] Fix failing --- .../src/concrete/vault/OffchainAssetReceiptVault.tiers.t.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.tiers.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.tiers.t.sol index ba8ca3eb..0cd7620c 100644 --- a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.tiers.t.sol +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.tiers.t.sol @@ -151,8 +151,8 @@ contract TiersTest is OffchainAssetReceiptVaultTest { abi.encode(999) ); - //Expect the revert with the exact revert reason - vm.expectRevert(abi.encodeWithSelector(UnauthorizedSenderTier.selector, bob, 999)); + //Expect the revert + vm.expectRevert(); vault.authorizeReceiptTransfer(bob, alice); } From 1a0265193278a229d159646cb9a98c574b372f87 Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Tue, 2 Jul 2024 14:23:56 +0400 Subject: [PATCH 11/12] Create setUpAddressesAndBounds and setUpVault functions and update one test --- .../OffchainAssetReceiptVault.handler.t.sol | 51 ++++++++++++++----- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol index 0a1e8d6f..60a3f9d1 100644 --- a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol @@ -13,6 +13,36 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { address sender, address owner, uint256 assets, uint256 shares, uint256 id, bytes receiptInformation ); + function setUpAddressesAndBounds( + uint256 fuzzedKeyAlice, + uint256 fuzzedKeyBob, + uint256 fuzzedKeyJohn, + uint256 balance, + uint256 referenceBlockNumber, + uint256 certifyUntil + ) internal view returns (address alice, address bob, address john, uint256, uint256, uint256) { + alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1); + bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); + john = vm.addr((fuzzedKeyJohn % (SECP256K1_ORDER - 1)) + 1); + + balance = bound(balance, 1, type(uint256).max); // Bound from one to avoid ZeroAssets + referenceBlockNumber = bound(referenceBlockNumber, 1, block.number); + certifyUntil = bound(certifyUntil, 1, type(uint32).max - 1); // substruct 1 for next bound + + return (alice, bob, john, balance, referenceBlockNumber, certifyUntil); + } + + function setUpVault(address alice, string memory assetName, string memory assetSymbol) + internal + returns (OffchainAssetReceiptVault vault, ReceiptContract receipt) + { + vm.recordLogs(); + vault = createVault(alice, assetName, assetSymbol); + Vm.Log[] memory logs = vm.getRecordedLogs(); + receipt = getReceipt(logs); + return (vault, receipt); + } + /// Test testReceiptTransfer to self with handler role function testReceiptTransferHandler( uint256 fuzzedKeyAlice, @@ -24,13 +54,10 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { bool forceUntil, uint256 balance ) external { - // Ensure the fuzzed key is within the valid range for secp256k1 - address alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1); - address bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); - - balance = bound(balance, 1, type(uint256).max); // Bound from one to avoid ZeroAssets - referenceBlockNumber = bound(referenceBlockNumber, 1, block.number); - certifyUntil = bound(certifyUntil, 1, type(uint32).max - 1); // substruct 1 for next bound + address alice; + address bob; + (alice, bob,, balance, referenceBlockNumber, certifyUntil) = + setUpAddressesAndBounds(fuzzedKeyAlice, fuzzedKeyBob, 0, balance, referenceBlockNumber, certifyUntil); // Need setting future timestamp so system gets unsertified but transfer is possible // due to a handler role @@ -38,12 +65,9 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { vm.assume(alice != bob); - // Start recording logs - vm.recordLogs(); - OffchainAssetReceiptVault vault = createVault(alice, assetName, assetName); - Vm.Log[] memory logs = vm.getRecordedLogs(); - - ReceiptContract receipt = getReceipt(logs); + OffchainAssetReceiptVault vault; + ReceiptContract receipt; + (vault, receipt) = setUpVault(alice, assetName, assetName); // Prank as Alice to grant roles vm.startPrank(alice); @@ -55,7 +79,6 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { // Call the certify function vault.certify(certifyUntil, referenceBlockNumber, forceUntil, bytes("")); - // Cannot fuzz assets value due to variable limits vault.deposit(balance, bob, 1, bytes("")); vm.stopPrank(); From 59f21b21cc80b096aa466fbb5f89a0f072b6ec2b Mon Sep 17 00:00:00 2001 From: ninokeldishvili Date: Tue, 2 Jul 2024 14:29:15 +0400 Subject: [PATCH 12/12] Update other test --- .../OffchainAssetReceiptVault.handler.t.sol | 47 ++++++++----------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol index 60a3f9d1..e1eb43f8 100644 --- a/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol +++ b/test/foundry/src/concrete/vault/OffchainAssetReceiptVault.handler.t.sol @@ -21,6 +21,7 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { uint256 referenceBlockNumber, uint256 certifyUntil ) internal view returns (address alice, address bob, address john, uint256, uint256, uint256) { + // Ensure the fuzzed key is within the valid range for secp256k alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1); bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); john = vm.addr((fuzzedKeyJohn % (SECP256K1_ORDER - 1)) + 1); @@ -105,14 +106,12 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { bool forceUntil, uint256 balance ) external { - // Ensure the fuzzed key is within the valid range for secp256k1 - address alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1); - address bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); - address john = vm.addr((fuzzedKeyJohn % (SECP256K1_ORDER - 1)) + 1); - - balance = bound(balance, 1, type(uint256).max); // Bound from one to avoid ZeroAssets - referenceBlockNumber = bound(referenceBlockNumber, 1, block.number); - certifyUntil = bound(certifyUntil, 1, type(uint32).max - 1); // substruct 1 for next bound + address alice; + address bob; + address john; + (alice, bob, john, balance, referenceBlockNumber, certifyUntil) = setUpAddressesAndBounds( + fuzzedKeyAlice, fuzzedKeyBob, fuzzedKeyJohn, balance, referenceBlockNumber, certifyUntil + ); // Need setting future timestamp so system gets uncertified but transfer is possible // due to a handler role @@ -122,12 +121,9 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { vm.assume(alice != john); vm.assume(bob != john); - // Start recording logs - vm.recordLogs(); - OffchainAssetReceiptVault vault = createVault(alice, assetName, assetName); - Vm.Log[] memory logs = vm.getRecordedLogs(); - - ReceiptContract receipt = getReceipt(logs); + OffchainAssetReceiptVault vault; + ReceiptContract receipt; + (vault, receipt) = setUpVault(alice, assetName, assetName); // Prank as Alice to grant roles vm.startPrank(alice); @@ -166,14 +162,12 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { bool forceUntil, uint256 balance ) external { - // Ensure the fuzzed key is within the valid range for secp256k1 - address alice = vm.addr((fuzzedKeyAlice % (SECP256K1_ORDER - 1)) + 1); - address bob = vm.addr((fuzzedKeyBob % (SECP256K1_ORDER - 1)) + 1); - address john = vm.addr((fuzzedKeyJohn % (SECP256K1_ORDER - 1)) + 1); - - balance = bound(balance, 1, type(uint256).max); // Bound from one to avoid ZeroAssets - referenceBlockNumber = bound(referenceBlockNumber, 1, block.number); - certifyUntil = bound(certifyUntil, 1, type(uint32).max - 1); // substruct 1 for next bound + address alice; + address bob; + address john; + (alice, bob, john, balance, referenceBlockNumber, certifyUntil) = setUpAddressesAndBounds( + fuzzedKeyAlice, fuzzedKeyBob, fuzzedKeyJohn, balance, referenceBlockNumber, certifyUntil + ); // Need setting future timestamp so system gets uncertified but transfer is possible // due to a handler role @@ -183,12 +177,9 @@ contract OffchainAssetReceiptVaultHandlerTest is OffchainAssetReceiptVaultTest { vm.assume(alice != john); vm.assume(bob != john); - // Start recording logs - vm.recordLogs(); - OffchainAssetReceiptVault vault = createVault(alice, assetName, assetName); - Vm.Log[] memory logs = vm.getRecordedLogs(); - - ReceiptContract receipt = getReceipt(logs); + OffchainAssetReceiptVault vault; + ReceiptContract receipt; + (vault, receipt) = setUpVault(alice, assetName, assetName); // Prank as Alice to grant roles vm.startPrank(alice);