@@ -800,8 +800,8 @@ describe("sponsored_cctp_src_periphery.deposit", () => {
800800 messageSentEventData ,
801801 ] ) ;
802802
803- let rentClaimAccount = await program . account . rentClaim . fetch ( rentClaim ) ;
804- assert . isTrue ( rentClaimAccount . amount . eq ( new BN ( 0 ) ) , "No debt should be accrued when rent_fund had funding" ) ;
803+ let rentClaimAccount = await program . account . rentClaim . fetchNullable ( rentClaim ) ;
804+ assert . isNull ( rentClaimAccount , "No debt should be accrued and account closed when rent_fund had funding" ) ;
805805
806806 // Withdraw all rent_fund balance to test debt accrual.
807807 let rentFundBalance = await connection . getBalance ( rentFund ) ;
@@ -849,4 +849,108 @@ describe("sponsored_cctp_src_periphery.deposit", () => {
849849 ) ;
850850 assert . isNull ( await program . account . rentClaim . fetchNullable ( rentClaim ) , "Rent claim account should be closed" ) ;
851851 } ) ;
852+
853+ it ( "Accrue and partially repay rent_fund debt" , async ( ) => {
854+ // Withdraw all rent_fund balance to test debt accrual.
855+ let rentFundBalance = await connection . getBalance ( rentFund ) ;
856+ await program . methods
857+ . withdrawRentFund ( { amount : new BN ( rentFundBalance . toString ( ) ) } )
858+ . accounts ( {
859+ recipient : owner ,
860+ programData,
861+ } )
862+ . rpc ( ) ;
863+
864+ [ rentClaim ] = PublicKey . findProgramAddressSync (
865+ [ Buffer . from ( "rent_claim" ) , depositor . publicKey . toBuffer ( ) ] ,
866+ program . programId
867+ ) ;
868+ let nonce = crypto . randomBytes ( 32 ) ;
869+ const deadline = ethers . BigNumber . from ( Math . floor ( Date . now ( ) / 1000 ) + 3600 ) ;
870+
871+ const quoteData : SponsoredCCTPQuote = {
872+ sourceDomain,
873+ destinationDomain : remoteDomain . toNumber ( ) ,
874+ mintRecipient : ethers . utils . hexlify ( mintRecipient ) ,
875+ amount : burnAmount ,
876+ burnToken : ethers . utils . hexlify ( burnToken . toBuffer ( ) ) ,
877+ destinationCaller : ethers . utils . hexlify ( destinationCaller ) ,
878+ maxFee,
879+ minFinalityThreshold,
880+ nonce : ethers . utils . hexlify ( nonce ) ,
881+ deadline,
882+ maxBpsToSponsor,
883+ maxUserSlippageBps,
884+ finalRecipient : ethers . utils . hexlify ( finalRecipient ) ,
885+ finalToken : ethers . utils . hexlify ( finalToken ) ,
886+ executionMode,
887+ actionData,
888+ } ;
889+ let { quote, signature } = getEncodedQuoteWithSignature ( quoteSigner , quoteData ) ;
890+
891+ const depositAccounts = {
892+ signer : depositor . publicKey ,
893+ payer : depositor . publicKey ,
894+ state,
895+ rentFund,
896+ usedNonce : getUsedNonce ( nonce ) ,
897+ rentClaim,
898+ depositorTokenAccount,
899+ burnToken,
900+ denylistAccount,
901+ tokenMessengerMinterSenderAuthority,
902+ messageTransmitter,
903+ tokenMessenger,
904+ remoteTokenMessenger,
905+ tokenMinter,
906+ localToken,
907+ cctpEventAuthority,
908+ tokenProgram,
909+ messageSentEventData : messageSentEventData . publicKey ,
910+ program : program . programId ,
911+ } ;
912+
913+ let depositIx = await program . methods . depositForBurn ( { quote, signature } ) . accounts ( depositAccounts ) . instruction ( ) ;
914+ await sendTransactionWithExistingLookupTable ( connection , [ depositIx ] , lookupTableAccount , depositor , [
915+ messageSentEventData ,
916+ ] ) ;
917+
918+ let rentClaimAccount = await program . account . rentClaim . fetch ( rentClaim ) ;
919+ const usedNonceBalance = await connection . getBalance ( depositAccounts . usedNonce ) ;
920+ const messageSentEventDataBalance = await connection . getBalance ( depositAccounts . messageSentEventData ) ;
921+ rentFundBalance = await connection . getBalance ( rentFund ) ;
922+ const fullClaimAmount = new BN ( usedNonceBalance + messageSentEventDataBalance + rentFundBalance ) ;
923+ assert . isTrue (
924+ rentClaimAccount . amount . eq ( fullClaimAmount ) ,
925+ "Rent claim should have accrued debt for account creation"
926+ ) ;
927+
928+ // Without funding rent claim account should keep the debt.
929+ await program . methods
930+ . repayRentFundDebt ( )
931+ . accounts ( { recipient : depositor . publicKey , program : program . programId } )
932+ . rpc ( ) ;
933+ rentClaimAccount = await program . account . rentClaim . fetch ( rentClaim ) ;
934+ assert . isTrue ( rentClaimAccount . amount . eq ( fullClaimAmount ) , "Rent claim should not been repaid" ) ;
935+
936+ // Test partial repayment of 1 lamport (rent_fund should already hold its minimum rent-free balance)
937+ const partialRepayment = 1 ;
938+ await requestAndConfirmAirdrop ( connection , rentFund , partialRepayment ) ;
939+ const userBalanceBefore = await connection . getBalance ( depositor . publicKey ) ;
940+ await program . methods
941+ . repayRentFundDebt ( )
942+ . accounts ( { recipient : depositor . publicKey , program : program . programId } )
943+ . rpc ( ) ;
944+ const userBalanceAfter = await connection . getBalance ( depositor . publicKey ) ;
945+ assert . strictEqual (
946+ userBalanceAfter - userBalanceBefore ,
947+ partialRepayment ,
948+ "User should have been refunded only part of the claim"
949+ ) ;
950+ rentClaimAccount = await program . account . rentClaim . fetch ( rentClaim ) ;
951+ assert . isTrue (
952+ rentClaimAccount . amount . eq ( fullClaimAmount . sub ( new BN ( partialRepayment ) ) ) ,
953+ "Rent claim should have been partially repaid"
954+ ) ;
955+ } ) ;
852956} ) ;
0 commit comments