@@ -598,6 +598,7 @@ contract TestRateLimit is Test, IRateLimiterEvents {
598
598
599
599
TrimmedAmount memory transferAmount = TrimmedAmount (10 , 8 );
600
600
token.approve (address (nttManager), type (uint256 ).max);
601
+ // transfer 10 tokens from user_A -> user_B via the nttManager
601
602
nttManager.transfer (
602
603
transferAmount.untrim (decimals), chainId, toWormholeFormat (user_B), false , new bytes (1 )
603
604
);
@@ -609,7 +610,8 @@ contract TestRateLimit is Test, IRateLimiterEvents {
609
610
assertEq (token.balanceOf (user_A), mintAmount.sub (transferAmount).untrim (decimals));
610
611
611
612
{
612
- // assert outbound rate limit decreased
613
+ // consumed capacity on the outbound side
614
+ // assert outbound capacity decreased
613
615
IRateLimiter.RateLimitParams memory outboundLimitParams =
614
616
nttManager.getOutboundLimitParams ();
615
617
assertEq (
@@ -639,7 +641,151 @@ contract TestRateLimit is Test, IRateLimiterEvents {
639
641
assertEq (token.balanceOf (user_A), mintAmount.untrim (decimals));
640
642
641
643
{
642
- // assert that the inbound limits decreased
644
+ // consume capacity on the inbound side
645
+ // assert that the inbound capacity decreased
646
+ IRateLimiter.RateLimitParams memory inboundLimitParams =
647
+ nttManager.getInboundLimitParams (TransceiverHelpersLib.SENDING_CHAIN_ID);
648
+ assertEq (
649
+ inboundLimitParams.currentCapacity.getAmount (),
650
+ inboundLimitParams.limit.sub (transferAmount).getAmount ()
651
+ );
652
+ assertEq (inboundLimitParams.lastTxTimestamp, receiveTime);
653
+ }
654
+
655
+ {
656
+ // assert that outbound limit is at max again (because of backflow)
657
+ IRateLimiter.RateLimitParams memory outboundLimitParams =
658
+ nttManager.getOutboundLimitParams ();
659
+ assertEq (
660
+ outboundLimitParams.currentCapacity.getAmount (),
661
+ outboundLimitParams.limit.getAmount ()
662
+ );
663
+ assertEq (outboundLimitParams.lastTxTimestamp, receiveTime);
664
+ }
665
+
666
+ // go 1 second into the future
667
+ uint256 sendAgainTime = receiveTime + 1 ;
668
+ vm.warp (sendAgainTime);
669
+
670
+ // transfer 10 back to the contract
671
+ vm.startPrank (user_A);
672
+
673
+ nttManager.transfer (
674
+ transferAmount.untrim (decimals),
675
+ TransceiverHelpersLib.SENDING_CHAIN_ID,
676
+ toWormholeFormat (user_B),
677
+ false ,
678
+ new bytes (1 )
679
+ );
680
+
681
+ vm.stopPrank ();
682
+
683
+ {
684
+ // assert outbound rate limit decreased
685
+ IRateLimiter.RateLimitParams memory outboundLimitParams =
686
+ nttManager.getOutboundLimitParams ();
687
+ assertEq (
688
+ outboundLimitParams.currentCapacity.getAmount (),
689
+ outboundLimitParams.limit.sub (transferAmount).getAmount ()
690
+ );
691
+ assertEq (outboundLimitParams.lastTxTimestamp, sendAgainTime);
692
+ }
693
+
694
+ {
695
+ // assert that the inbound limit is at max again (because of backflow)
696
+ IRateLimiter.RateLimitParams memory inboundLimitParams =
697
+ nttManager.getInboundLimitParams (TransceiverHelpersLib.SENDING_CHAIN_ID);
698
+ assertEq (
699
+ inboundLimitParams.currentCapacity.getAmount (), inboundLimitParams.limit.getAmount ()
700
+ );
701
+ assertEq (inboundLimitParams.lastTxTimestamp, sendAgainTime);
702
+ }
703
+ }
704
+
705
+ // helper functions
706
+ function setupToken () public returns (address , address , DummyToken, uint8 ) {
707
+ address user_A = address (0x123 );
708
+ address user_B = address (0x456 );
709
+
710
+ DummyToken token = DummyToken (nttManager.token ());
711
+
712
+ uint8 decimals = token.decimals ();
713
+ assertEq (decimals, 18 );
714
+
715
+ return (user_A, user_B, token, decimals);
716
+ }
717
+
718
+ function initializeTransceivers () public returns (ITransceiverReceiver[] memory ) {
719
+ (DummyTransceiver e1 , DummyTransceiver e2 ) =
720
+ TransceiverHelpersLib.setup_transceivers (nttManager);
721
+
722
+ ITransceiverReceiver[] memory transceivers = new ITransceiverReceiver [](2 );
723
+ transceivers[0 ] = e1;
724
+ transceivers[1 ] = e2;
725
+
726
+ return transceivers;
727
+ }
728
+
729
+ // transfer tokens from user_A to user_B
730
+ // this consumes capacity on the outbound side
731
+ // send tokens from user_B to user_A
732
+ // this consumes capacity on the inbound side
733
+ // send tokens from user_A to user_B
734
+ // this should consume capacity on the outbound side
735
+ // and backfill the inbound side
736
+ function testFuzz_CircularFlowBackFilling (uint64 mintAmt , uint64 transferAmt ) public {
737
+ vm.assume (transferAmt > 0 && transferAmt < mintAmt);
738
+
739
+ (address user_A , address user_B , DummyToken token , uint8 decimals ) = setupToken ();
740
+
741
+ TrimmedAmount memory mintAmount = TrimmedAmount (mintAmt, 8 );
742
+ token.mintDummy (address (user_A), mintAmount.untrim (decimals));
743
+ nttManager.setOutboundLimit (mintAmount.untrim (decimals));
744
+
745
+ // transfer 10 tokens
746
+ vm.startPrank (user_A);
747
+
748
+ TrimmedAmount memory transferAmount = TrimmedAmount (transferAmt, 8 );
749
+ token.approve (address (nttManager), type (uint256 ).max);
750
+ // transfer tokens from user_A -> user_B via the nttManager
751
+ nttManager.transfer (
752
+ transferAmount.untrim (decimals), chainId, toWormholeFormat (user_B), false , new bytes (1 )
753
+ );
754
+
755
+ vm.stopPrank ();
756
+
757
+ // assert nttManager has 10 tokens and user_A has 10 fewer tokens
758
+ assertEq (token.balanceOf (address (nttManager)), transferAmount.untrim (decimals));
759
+ assertEq (token.balanceOf (user_A), mintAmount.sub (transferAmount).untrim (decimals));
760
+
761
+ {
762
+ // consumed capacity on the outbound side
763
+ // assert outbound capacity decreased
764
+ IRateLimiter.RateLimitParams memory outboundLimitParams =
765
+ nttManager.getOutboundLimitParams ();
766
+ assertEq (
767
+ outboundLimitParams.currentCapacity.getAmount (),
768
+ outboundLimitParams.limit.sub (transferAmount).getAmount ()
769
+ );
770
+ assertEq (outboundLimitParams.lastTxTimestamp, initialBlockTimestamp);
771
+ }
772
+
773
+ // go 1 second into the future
774
+ uint256 receiveTime = initialBlockTimestamp + 1 ;
775
+ vm.warp (receiveTime);
776
+
777
+ ITransceiverReceiver[] memory transceivers = initializeTransceivers ();
778
+ // now receive tokens from user_B -> user_A
779
+ TransceiverHelpersLib.attestTransceiversHelper (
780
+ user_A, 0 , chainId, nttManager, nttManager, transferAmount, mintAmount, transceivers
781
+ );
782
+
783
+ // assert that user_A has original amount
784
+ assertEq (token.balanceOf (user_A), mintAmount.untrim (decimals));
785
+
786
+ {
787
+ // consume capacity on the inbound side
788
+ // assert that the inbound capacity decreased
643
789
IRateLimiter.RateLimitParams memory inboundLimitParams =
644
790
nttManager.getInboundLimitParams (TransceiverHelpersLib.SENDING_CHAIN_ID);
645
791
assertEq (
0 commit comments