From 0ea66cc847cace6b12f01c7ccebe71fb5eabf759 Mon Sep 17 00:00:00 2001 From: marcomariscal <42938673+marcomariscal@users.noreply.github.com> Date: Thu, 11 Jul 2024 12:06:27 -0700 Subject: [PATCH] feat: save user announcements to local storage and last fetched block (#685) * feat: set the last fetched block as the start block * feat: handle caching user announcements and latest fetched block * feat: show user announcements if there are any * fix: handle watching/loading announcements * fix: parse out lastFetchedBlock and fix user announcement loading logic * chore: log * feat: handle block data caching * feat: show most recent block data if exists * fix: type check * feat: handle user announcements already present and sign language * feat: only show fetching when no user announcements * feat: fetching latest from last fetched block component * feat: fetching latest translation for cn * feat: clear local storage button and functionality * fix: start block handling logic * feat: dedupe user announcements * fix: logic * fix: minimize debugging logs on userAnnouncement changes * feat: handle scanning latest announcements from last fetched block * feat: sort by timestamp explicitly * feat: no loading sequence when there are announcements * fix: need sig lately verbiage * fix: add need sig lately to cn * fix: little more mb * fix: no withdraw verbiage on need-sig-lately * feat: handle need sig * Update frontend/src/i18n/locales/en-US.json Co-authored-by: Gary Ghayrat <61768337+garyghayrat@users.noreply.github.com> * feat: handle sign button instead of needs sig * Update frontend/src/i18n/locales/zh-CN.json Co-authored-by: Gary Ghayrat <61768337+garyghayrat@users.noreply.github.com> * fix: move local storage clear button above lang * fix: spacing more uniform * fix: use computed ref as param, and set setIsInWithdrawFlow to false on mount * feat: sign and withdraw * fix: contract periphery tests (#688) * fix: explicitly sort the tokens by addr * fix: use vm.computeCreateAddress * fix: mirror test sender params * fix: use actual owner * fix: add back gnosis * Remove all reference to INFURA_ID (#687) --------- Co-authored-by: John Feras * fix: use balanceIndex to ensure that the correct balance is fetched from the stealthBalances array * fix: dedupe by tx hash and receiver instead of just tx hash * fix: include receiver to derive isWithdrawn * fix: img --------- Co-authored-by: Gary Ghayrat <61768337+garyghayrat@users.noreply.github.com> Co-authored-by: John Feras --- .github/workflows/ci.yaml | 1 - contracts-core/.env.example | 1 - contracts-periphery/Makefile | 2 +- .../script/ApproveBatchSendTokens.s.sol | 3 +- .../script/DeployBatchSend.s.sol | 2 +- .../test/ApproveBatchSendTokens.t.sol | 8 +- .../test/DeployBatchSend.t.sol | 2 +- contracts-periphery/test/UmbraBatchSend.t.sol | 14 + frontend/.env.example | 1 - .../src/components/AccountReceiveTable.vue | 99 +++++- frontend/src/components/WithdrawForm.vue | 56 +++- frontend/src/i18n/locales/en-US.json | 6 + frontend/src/i18n/locales/zh-CN.json | 7 + frontend/src/layouts/BaseLayout.vue | 28 +- frontend/src/pages/AccountReceive.vue | 289 ++++++++++++++++-- frontend/src/store/settings.ts | 8 +- frontend/src/store/wallet.ts | 3 +- umbra-js/.env.example | 1 - umbra-js/hardhat.config.ts | 11 +- umbra-js/test/cns.test.ts | 8 +- umbra-js/test/utils.test.ts | 44 +-- 21 files changed, 490 insertions(+), 104 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 375b1173b..630cdb469 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -28,7 +28,6 @@ env: GNOSIS_CHAIN_RPC_URL: ${{ secrets.GNOSIS_CHAIN_RPC_URL }} BASE_RPC_URL: $${{ secrets.BASE_RPC_URL }} FOUNDRY_PROFILE: ci - INFURA_ID: ${{ secrets.INFURA_ID }} WALLET_CONNECT_PROJECT_ID: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} jobs: diff --git a/contracts-core/.env.example b/contracts-core/.env.example index 4777fb8b0..b7951bc4b 100644 --- a/contracts-core/.env.example +++ b/contracts-core/.env.example @@ -1,4 +1,3 @@ -INFURA_ID=zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz MNEMONIC=here is where your twelve words mnemonic should be put my friend DEPLOY_GSN=false ETHERSCAN_VERIFICATION_API_KEY="YOUR_API_KEY" diff --git a/contracts-periphery/Makefile b/contracts-periphery/Makefile index 4d6262955..87a435aa5 100644 --- a/contracts-periphery/Makefile +++ b/contracts-periphery/Makefile @@ -13,4 +13,4 @@ install :; $(INSTALL_CMD) test :; forge test --sender 0x4f78F7f3482D9f1790649f9DD18Eec5A1Cc70F86 --no-match-contract ApproveBatchSendTokensTest test-gas :; forge test --match-path *.gas.t.sol snapshot-gas :; forge test --match-path *.gas.t.sol --gas-report > snapshot/.gas -coverage :; forge coverage --report lcov --report summary && sed -i'.bak' 's/SF:/SF:contracts-periphery\//gI' lcov.info +coverage :; forge coverage --sender 0x4f78F7f3482D9f1790649f9DD18Eec5A1Cc70F86 --report lcov --report summary && sed -i'.bak' 's/SF:/SF:contracts-periphery\//gI' lcov.info diff --git a/contracts-periphery/script/ApproveBatchSendTokens.s.sol b/contracts-periphery/script/ApproveBatchSendTokens.s.sol index 0ce27a100..5f29461a0 100644 --- a/contracts-periphery/script/ApproveBatchSendTokens.s.sol +++ b/contracts-periphery/script/ApproveBatchSendTokens.s.sol @@ -7,11 +7,12 @@ import {UmbraBatchSend} from "src/UmbraBatchSend.sol"; contract ApproveBatchSendTokens is Script { function run( + address _owner, address _umbraContractAddress, address _batchSendContractAddress, address[] calldata _tokenAddressesToApprove ) public { - vm.startBroadcast(); + vm.startBroadcast(_owner); for (uint256 _i = 0; _i < _tokenAddressesToApprove.length; _i++) { uint256 _currentAllowance = IERC20(_tokenAddressesToApprove[_i]).allowance( _batchSendContractAddress, _umbraContractAddress diff --git a/contracts-periphery/script/DeployBatchSend.s.sol b/contracts-periphery/script/DeployBatchSend.s.sol index 31ead2d4a..d840a5d5c 100644 --- a/contracts-periphery/script/DeployBatchSend.s.sol +++ b/contracts-periphery/script/DeployBatchSend.s.sol @@ -30,7 +30,7 @@ contract DeployBatchSend is Script { /// @notice Deploy the contract to the list of networks, function run() public { // Compute the address the contract will be deployed to - address expectedContractAddress = computeCreateAddress(msg.sender, EXPECTED_NONCE); + address expectedContractAddress = vm.computeCreateAddress(msg.sender, EXPECTED_NONCE); console2.log("Expected contract address: %s", expectedContractAddress); // Turn off fallback to default RPC URLs since they can be flaky. diff --git a/contracts-periphery/test/ApproveBatchSendTokens.t.sol b/contracts-periphery/test/ApproveBatchSendTokens.t.sol index cd7c29a0a..db28cd580 100644 --- a/contracts-periphery/test/ApproveBatchSendTokens.t.sol +++ b/contracts-periphery/test/ApproveBatchSendTokens.t.sol @@ -17,6 +17,7 @@ contract ApproveBatchSendTokensTest is Test { address constant WBTC_ADDRESS = 0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599; address[] tokensToApprove = [DAI_ADDRESS, LUSD_ADDRESS, RAI_ADDRESS, USDC_ADDRESS, USDT_ADDRESS, WBTC_ADDRESS]; + address owner = 0xB7EE870E2c49B2DEEe70003519cF056247Aac3D4; function setUp() public { vm.createSelectFork(vm.rpcUrl("mainnet"), 18_428_858); @@ -27,7 +28,10 @@ contract ApproveBatchSendTokensTest is Test { address[] memory tokenAddressesToApprove = new address[](1); tokenAddressesToApprove[0] = DAI_ADDRESS; approveTokensScript.run( - umbraContractAddressOnMainnet, batchSendContractAddressOnMainnet, tokenAddressesToApprove + owner, + umbraContractAddressOnMainnet, + batchSendContractAddressOnMainnet, + tokenAddressesToApprove ); assertEq( @@ -40,7 +44,7 @@ contract ApproveBatchSendTokensTest is Test { function test_ApproveMultipleTokens() public { approveTokensScript.run( - umbraContractAddressOnMainnet, batchSendContractAddressOnMainnet, tokensToApprove + owner, umbraContractAddressOnMainnet, batchSendContractAddressOnMainnet, tokensToApprove ); for (uint256 _i; _i < tokensToApprove.length; _i++) { diff --git a/contracts-periphery/test/DeployBatchSend.t.sol b/contracts-periphery/test/DeployBatchSend.t.sol index aeb185f33..4fd04797c 100644 --- a/contracts-periphery/test/DeployBatchSend.t.sol +++ b/contracts-periphery/test/DeployBatchSend.t.sol @@ -14,7 +14,7 @@ contract DeployBatchSendTest is DeployBatchSend, Test { bytes batchSendCode; function setUp() public { - expectedContractAddress = computeCreateAddress(sender, EXPECTED_NONCE); + expectedContractAddress = vm.computeCreateAddress(sender, EXPECTED_NONCE); umbraBatchSendTest = new UmbraBatchSend(IUmbra(UMBRA)); batchSendCode = address(umbraBatchSendTest).code; } diff --git a/contracts-periphery/test/UmbraBatchSend.t.sol b/contracts-periphery/test/UmbraBatchSend.t.sol index 65f1b602d..25eb3c20e 100644 --- a/contracts-periphery/test/UmbraBatchSend.t.sol +++ b/contracts-periphery/test/UmbraBatchSend.t.sol @@ -20,6 +20,18 @@ abstract contract UmbraBatchSendTest is DeployUmbraTest { error NotSorted(); error TooMuchEthSent(); + function _sortSendDataByToken(UmbraBatchSend.SendData[] storage arr) internal { + for (uint256 i = 0; i < arr.length - 1; i++) { + for (uint256 j = 0; j < arr.length - i - 1; j++) { + if (arr[j].tokenAddr > arr[j + 1].tokenAddr) { + UmbraBatchSend.SendData memory temp = arr[j]; + arr[j] = arr[j + 1]; + arr[j + 1] = temp; + } + } + } + } + function setUp() public virtual override { super.setUp(); router = new UmbraBatchSend(IUmbra(address(umbra))); @@ -94,6 +106,8 @@ abstract contract UmbraBatchSendTest is DeployUmbraTest { sendData.push(UmbraBatchSend.SendData(alice, address(token), amount, pkx, ciphertext)); sendData.push(UmbraBatchSend.SendData(bob, address(token), amount2, pkx, ciphertext)); + _sortSendDataByToken(sendData); + uint256 totalToll = toll * sendData.length; token.approve(address(router), totalAmount); token2.approve(address(router), totalAmount2); diff --git a/frontend/.env.example b/frontend/.env.example index ee9dccc1b..3062ba0bd 100644 --- a/frontend/.env.example +++ b/frontend/.env.example @@ -3,7 +3,6 @@ OPTIMISTIC_ETHERSCAN_API_KEY=yourOptimisticEtherscanApiKey POLYGONSCAN_API_KEY=yourPolygonscanApiKey ARBISCAN_API_KEY=yourArbiscanApiKey -INFURA_ID=yourKeyHere BLOCKNATIVE_API_KEY=yourKeyHere FORTMATIC_API_KEY=yourKeyHere PORTIS_API_KEY=yourKeyHere diff --git a/frontend/src/components/AccountReceiveTable.vue b/frontend/src/components/AccountReceiveTable.vue index b1147bdd3..a6858921e 100644 --- a/frontend/src/components/AccountReceiveTable.vue +++ b/frontend/src/components/AccountReceiveTable.vue @@ -60,12 +60,45 @@ >. -
- - {{ $t('AccountReceiveTable.most-recent-announcement') }} - {{ mostRecentAnnouncementBlockNumber }} / - {{ formatDate(mostRecentAnnouncementTimestamp * 1000) }} - {{ formatTime(mostRecentAnnouncementTimestamp * 1000) }} +
+ +
+ +
+ {{ $t('AccountReceiveTable.most-recent-announcement') }} + {{ mostRecentAnnouncementBlockNumber }} / + {{ formatDate(mostRecentAnnouncementTimestamp * 1000) }} + {{ formatTime(mostRecentAnnouncementTimestamp * 1000) }} +
+ + +
+
+ {{ + scanStatus === 'fetching' + ? $t('Receive.fetching') + : $t('Receive.fetching-latest-from-last-fetched-block') + }} + +
+
+ {{ + scanStatus === 'scanning latest from last fetched block' + ? $t('Receive.scanning-latest-from-last-fetched-block') + : $t('Receive.scanning') + }} + +
+
+
+
{{ $t('AccountReceiveTable.most-recent-mined') }} {{ mostRecentBlockNumber }} / @@ -385,7 +418,7 @@