Skip to content

Commit

Permalink
revert result handling
Browse files Browse the repository at this point in the history
  • Loading branch information
cryptoAtwill committed Dec 27, 2024
1 parent 5bb94d2 commit 0b1ab4b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
10 changes: 6 additions & 4 deletions contracts/contracts/lib/CrossMsgHelper.sol
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,13 @@ library CrossMsgHelper {
}

address recipient = crossMsg.to.rawAddress.extractEvmAddress().normalize();
// If the cross msg kind is Result, create result message should have handled the value correctly.
// If the execution is ok, value should be 0, else one should perform refund.
if (crossMsg.kind == IpcMsgKind.Transfer || crossMsg.kind == IpcMsgKind.Result) {
if (crossMsg.kind == IpcMsgKind.Transfer) {
return supplySource.transferFunds({recipient: payable(recipient), value: crossMsg.value});
} else if (crossMsg.kind == IpcMsgKind.Call) {
} else if (crossMsg.kind == IpcMsgKind.Call || crossMsg.kind == IpcMsgKind.Result) {
// For a Result message, the idea is to perform a call as this returns control back to the caller.
// If it's an account, there will be no code to invoke, so this will be have like a bare transfer.
// But if the original caller was a contract, this give it control so it can handle the result

// send the envelope directly to the entrypoint
// use supplySource so the tokens in the message are handled successfully
// and by the right supply source
Expand Down
14 changes: 13 additions & 1 deletion contracts/test/integration/L2PlusXNet.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {ActivityHelper} from "../helpers/ActivityHelper.sol";
import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {ISubnetActor} from "../../contracts/interfaces/ISubnetActor.sol";
import {IPCMsgType} from "../../contracts/enums/IPCMsgType.sol";
import {IIpcHandler} from "../../sdk/interfaces/IIpcHandler.sol";

import "forge-std/console.sol";

Expand Down Expand Up @@ -137,7 +138,7 @@ interface IGateway {
function fundWithToken(SubnetID calldata subnetId, FvmAddress calldata to, uint256 amount) external;
}

contract L2PlusSubnetTest is Test, IntegrationTestBase {
contract L2PlusSubnetTest is Test, IntegrationTestBase, IIpcHandler {
using SubnetIDHelper for SubnetID;
using CrossMsgHelper for IpcEnvelope;
using GatewayFacetsHelper for GatewayDiamond;
Expand All @@ -161,6 +162,17 @@ contract L2PlusSubnetTest is Test, IntegrationTestBase {
vm.deal(address(this), 10 ether);
}

// ======= implements ipc handler =======

/* solhint-disable-next-line unused-vars */
function handleIpcMessage(IpcEnvelope calldata envelope) external payable returns (bytes memory ret) {
ret = bytes("");
}

receive() external payable {}

// ======= internal util methods ========

function executeTopdownMessages(IpcEnvelope[] memory msgs, GatewayDiamond gw) internal {
uint256 minted_tokens;

Expand Down
16 changes: 9 additions & 7 deletions contracts/test/integration/MultiSubnet.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1150,16 +1150,18 @@ contract MultiSubnetTest is Test, IntegrationTestBase {
vm.deal(tokenSubnet.subnetActorAddr, DEFAULT_COLLATERAL_AMOUNT);
vm.deal(caller, 1 ether);

uint256 fundToSend = 10;
uint256 balance = 100;

// Fund an account in the subnet.
token.transfer(caller, fundToSend);
token.transfer(caller, balance);
vm.prank(caller);
token.approve(rootSubnet.gatewayAddr, fundToSend);
token.approve(rootSubnet.gatewayAddr, balance);

vm.prank(tokenSubnet.subnetActorAddr);
registerSubnetGW(DEFAULT_COLLATERAL_AMOUNT, tokenSubnet.subnetActorAddr, rootSubnet.gateway);

uint256 fundToSend = 10;

vm.prank(caller);
rootSubnet.gateway.manager().fundWithToken(tokenSubnet.id, FvmAddressHelper.from(address(caller)), fundToSend);

Expand Down Expand Up @@ -1190,14 +1192,14 @@ contract MultiSubnetTest is Test, IntegrationTestBase {
// but the caller is MockIpcContractRevert, which reverts whatever
// call made to `handleIpcMessage`, we should make sure:
// 1. The submission of checkpoint is never blocked
// 2. The fund is locked in the gateway as execution is rejected
submitBottomUpCheckpoint(checkpoint, tokenSubnet.subnetActor);

// because error result xnet message should have refunded the token
require(token.balanceOf(caller) == amount, "caller fund should not be locked in gateway");
require(
token.balanceOf(address(rootSubnet.gateway.manager())) == fundToSend - amount,
"fund should not be locked in gateway"
token.balanceOf(address(rootSubnet.gateway.manager())) == fundToSend,
"fund should still be locked in gateway"
);
require(token.balanceOf(caller) == balance - fundToSend, "fund should still be locked in gateway");
}

function testMultiSubnet_Token_CallFromChildToParent() public {
Expand Down

0 comments on commit 0b1ab4b

Please sign in to comment.