diff --git a/contracts/contracts/ccip/test/receiver/contract.tolk b/contracts/contracts/ccip/test/receiver/contract.tolk index ce01b29a3..cab87ed53 100644 --- a/contracts/contracts/ccip/test/receiver/contract.tolk +++ b/contracts/contracts/ccip/test/receiver/contract.tolk @@ -26,18 +26,7 @@ fun onInternalMessage(in: InMessage) { match (msg) { Receiver_CCIPReceive => { var st = lazy Storage.load(); - msg.validateAndConfirm({ - router: st.authorizedCaller, - minValue: ton("0.01"), - inMsg: { - senderAddress: in.senderAddress, - valueCoins: in.valueCoins, - }, - confirmationMsg: { - sendMode: SEND_MODE_CARRY_ALL_REMAINING_MESSAGE_VALUE, - } - }); - + match (st.behavior) { TestReceiverBehavior.Accept => { processAccept(msg, in.senderAddress) @@ -49,6 +38,20 @@ fun onInternalMessage(in: InMessage) { processConsumeAllGas() } } + + reserveToncoinsOnBalance(0, RESERVE_MODE_INCREASE_BY_ORIGINAL_BALANCE); + msg.validateAndConfirm({ + router: st.authorizedCaller, + minValue: ton("0.01"), + inMsg: { + senderAddress: in.senderAddress, + valueCoins: in.valueCoins, + }, + confirmationMsg: { + sendMode: SEND_MODE_CARRY_ALL_BALANCE, + } + }); + } TestReceiver_UpdateAuthorizedCaller => { onUpdateAuthorizedCaller(msg, in.senderAddress) diff --git a/contracts/tests/ccip/Receiver.spec.ts b/contracts/tests/ccip/Receiver.spec.ts index 02c3b9d34..dfd6e742c 100644 --- a/contracts/tests/ccip/Receiver.spec.ts +++ b/contracts/tests/ccip/Receiver.spec.ts @@ -1,5 +1,5 @@ import { Blockchain, SandboxContract, TreasuryContract } from '@ton/sandbox' -import { beginCell, toNano } from '@ton/core' +import { Address, beginCell, toNano } from '@ton/core' import { compile } from '@ton/blueprint' import '@ton/test-utils' @@ -258,4 +258,40 @@ describe('Receiver', () => { exitCode: -14, }) }) + + it('should keep original balance after succesfully receiving', async () => { + const contract = await blockchain.getContract(receiver.address) + const initialBalance = contract.balance + + const result = await receiver.sendCCIPReceive( + deployer.getSender(), + toNano('1'), + ccipReceiveSampleMessage, + ) + expect(result.transactions).toHaveTransaction({ + from: deployer.address, + to: receiver.address, + success: true, + deploy: false, + body: tr.builder.message.in.ccipReceive.encode(ccipReceiveSampleMessage).asCell(), + }) + + const tx = result.transactions.find( + (tx) => + tx.inMessage && + tx.inMessage.info.src && + tx.inMessage.info.src instanceof Address && + tx.inMessage.info.src.equals(deployer.address) && + tx.inMessage.info.dest && + tx.inMessage.info.dest instanceof Address && + tx.inMessage.info.dest.equals(receiver.address), + ) + if (!tx || tx.description.type != 'generic') { + throw new Error('Expected an internal message') + } + const storageFees = tx.description.storagePhase?.storageFeesCollected || toNano('0') + + const finalBalance = (await blockchain.getContract(receiver.address)).balance + expect(finalBalance).toEqual(initialBalance - storageFees) + }) })