Skip to content

Commit

Permalink
fix: try/catch precompile function call and check bool value returned…
Browse files Browse the repository at this point in the history
… by precompile functions as status of success (#44)

Co-authored-by: cloud8little <34291844+cloud8little@users.noreply.github.com>
  • Loading branch information
adu-web3 and cloud8little authored May 29, 2024
1 parent 6a46b0d commit b834259
Show file tree
Hide file tree
Showing 12 changed files with 427 additions and 100 deletions.
114 changes: 114 additions & 0 deletions script/TestPrecompileErrorFixed.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
pragma solidity ^0.8.19;

import "forge-std/Script.sol";
import {ERC20PresetFixedSupply} from "@openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol";
import "@openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol";
import "../src/interfaces/IClientChainGateway.sol";
import "../src/interfaces/IVault.sol";
import "../src/interfaces/IExocoreGateway.sol";
import "src/core/ExocoreGateway.sol";
import "../src/interfaces/precompiles/IDelegation.sol";
import "../src/interfaces/precompiles/IDeposit.sol";
import "../src/interfaces/precompiles/IWithdrawPrinciple.sol";
import "../src/interfaces/precompiles/IClaimReward.sol";
import "../src/storage/GatewayStorage.sol";
import "@layerzero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol";
import "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/GUID.sol";
import "@layerzero-v2/protocol/contracts/libs/AddressCast.sol";
import "src/core/ClientChainGateway.sol";
import {NonShortCircuitEndpointV2Mock} from "../test/mocks/NonShortCircuitEndpointV2Mock.sol";
import {BaseScript} from "./BaseScript.sol";

contract DepositScript is BaseScript {
using AddressCast for address;

uint256 constant TEST_DEPOSIT_AMOUNT = 100;
uint256 constant TEST_WITHDRAWAL_AMOUNT = 123;

function setUp() public virtual override {
super.setUp();

exocoreRPCURL = vm.envString("EXOCORE_LOCAL_RPC");

restakeToken = ERC20PresetFixedSupply(erc20TokenAddress);
clientChainLzEndpoint = NonShortCircuitEndpointV2Mock(address(0xa));
clientGateway = ClientChainGateway(payable(address(0xb)));

string memory testContracts = vm.readFile("script/testContracts.json");

exocoreGateway = IExocoreGateway(payable(stdJson.readAddress(testContracts, ".exocore.exocoreGateway")));
require(address(exocoreGateway) != address(0), "exocoreGateway address should not be empty");

exocoreLzEndpoint = ILayerZeroEndpointV2(stdJson.readAddress(testContracts, ".exocore.lzEndpoint"));
require(address(exocoreLzEndpoint) != address(0), "exocoreLzEndpoint address should not be empty");

exocore = vm.createSelectFork(exocoreRPCURL);
vm.startBroadcast(exocoreGenesis.privateKey);
if (depositor.addr.balance < 1 ether) {
(bool sent,) = depositor.addr.call{value: 2 ether}("");
require(sent, "Failed to send Ether");
}
if (address(exocoreGateway).balance < 1 ether) {
(bool sent,) = address(exocoreGateway).call{value: 2 ether}("");
require(sent, "Failed to send Ether");
}
vm.stopBroadcast();

// bind precompile mock contracts code to constant precompile address
bytes memory DepositMockCode = vm.getDeployedCode("DepositMock.sol");
vm.etch(DEPOSIT_PRECOMPILE_ADDRESS, DepositMockCode);

bytes memory DelegationMockCode = vm.getDeployedCode("DelegationMock.sol");
vm.etch(DELEGATION_PRECOMPILE_ADDRESS, DelegationMockCode);

bytes memory WithdrawPrincipleMockCode = vm.getDeployedCode("WithdrawPrincipleMock.sol");
vm.etch(WITHDRAW_PRECOMPILE_ADDRESS, WithdrawPrincipleMockCode);

bytes memory WithdrawRewardMockCode = vm.getDeployedCode("ClaimRewardMock.sol");
vm.etch(CLAIM_REWARD_PRECOMPILE_ADDRESS, WithdrawRewardMockCode);
}

function run() public {
bytes memory depositMsg = abi.encodePacked(
GatewayStorage.Action.REQUEST_DEPOSIT,
abi.encodePacked(bytes32(bytes20(address(restakeToken)))),
abi.encodePacked(bytes32(bytes20(depositor.addr))),
uint256(TEST_DEPOSIT_AMOUNT)
);

vm.selectFork(exocore);
vm.startBroadcast(depositor.privateKey);
uint64 nonce = exocoreGateway.nextNonce(clientChainId, address(clientGateway).toBytes32());
exocoreLzEndpoint.lzReceive(
Origin(clientChainId, address(clientGateway).toBytes32(), nonce),
address(exocoreGateway),
GUID.generate(
nonce, clientChainId, address(clientGateway), exocoreChainId, address(exocoreGateway).toBytes32()
),
depositMsg,
bytes("")
);
vm.stopBroadcast();

bytes memory withdrawMsg = abi.encodePacked(
GatewayStorage.Action.REQUEST_WITHDRAW_PRINCIPLE_FROM_EXOCORE,
abi.encodePacked(bytes32(bytes20(address(restakeToken)))),
abi.encodePacked(bytes32(bytes20(depositor.addr))),
uint256(TEST_WITHDRAWAL_AMOUNT)
);

vm.selectFork(exocore);
vm.startBroadcast(depositor.privateKey);
nonce = exocoreGateway.nextNonce(clientChainId, address(clientGateway).toBytes32());
exocoreLzEndpoint.lzReceive(
Origin(clientChainId, address(clientGateway).toBytes32(), nonce),
address(exocoreGateway),
GUID.generate(
nonce, clientChainId, address(clientGateway), exocoreChainId, address(exocoreGateway).toBytes32()
),
withdrawMsg,
bytes("")
);
vm.stopBroadcast();
}
}
84 changes: 84 additions & 0 deletions script/TestPrecompileErrorFixed_Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
pragma solidity ^0.8.19;

import "forge-std/Script.sol";
import {ERC20PresetFixedSupply} from "@openzeppelin-contracts/contracts/token/ERC20/presets/ERC20PresetFixedSupply.sol";
import "@openzeppelin-contracts/contracts/proxy/transparent/ProxyAdmin.sol";
import "../src/interfaces/IClientChainGateway.sol";
import "../src/interfaces/IVault.sol";
import "../src/interfaces/IExocoreGateway.sol";
import "src/core/ExocoreGateway.sol";
import "../src/interfaces/precompiles/IDelegation.sol";
import "../src/interfaces/precompiles/IDeposit.sol";
import "../src/interfaces/precompiles/IWithdrawPrinciple.sol";
import "../src/interfaces/precompiles/IClaimReward.sol";
import "../src/storage/GatewayStorage.sol";
import "@layerzero-v2/protocol/contracts/interfaces/ILayerZeroEndpointV2.sol";
import "@layerzerolabs/lz-evm-protocol-v2/contracts/libs/GUID.sol";
import "@layerzero-v2/protocol/contracts/libs/AddressCast.sol";
import "src/core/ClientChainGateway.sol";
import {NonShortCircuitEndpointV2Mock} from "../test/mocks/NonShortCircuitEndpointV2Mock.sol";
import {BaseScript} from "./BaseScript.sol";

contract DepositScript is BaseScript {
using AddressCast for address;

uint256 constant WITHDRAWAL_AMOUNT = 123;

function setUp() public virtual override {
super.setUp();

exocoreRPCURL = vm.envString("EXOCORE_LOCAL_RPC");

string memory deployedContracts = vm.readFile("script/deployedContracts.json");

restakeToken = ERC20PresetFixedSupply(stdJson.readAddress(deployedContracts, ".clientChain.erc20Token"));
require(address(restakeToken) != address(0), "restakeToken address should not be empty");

exocore = vm.createSelectFork(exocoreRPCURL);
vm.startBroadcast(exocoreGenesis.privateKey);
if (deployer.addr.balance < 1 ether) {
(bool sent,) = deployer.addr.call{value: 1 ether}("");
require(sent, "Failed to send Ether");
}
vm.stopBroadcast();
}

function run() public {
_deploy();

string memory testContracts = "testContracts";
string memory exocoreContracts = "exocoreContracts";

vm.serializeAddress(exocoreContracts, "lzEndpoint", address(exocoreLzEndpoint));
string memory exocoreContractsOutput =
vm.serializeAddress(exocoreContracts, "exocoreGateway", address(exocoreGateway));

string memory finalJson = vm.serializeString(testContracts, "exocore", exocoreContractsOutput);

vm.writeJson(finalJson, "script/testContracts.json");
}

function _deploy() internal {
clientChainLzEndpoint = NonShortCircuitEndpointV2Mock(address(0xa));
clientGateway = ClientChainGateway(payable(address(0xb)));

vm.selectFork(exocore);

vm.startBroadcast(deployer.privateKey);
exocoreLzEndpoint = new NonShortCircuitEndpointV2Mock(exocoreChainId, exocoreValidatorSet.addr);
ProxyAdmin proxyAdmin = new ProxyAdmin();
ExocoreGateway exocoreGatewayLogic = new ExocoreGateway(address(exocoreLzEndpoint));
exocoreGateway = ExocoreGateway(
payable(address(new TransparentUpgradeableProxy(address(exocoreGatewayLogic), address(proxyAdmin), "")))
);
ExocoreGateway(payable(address(exocoreGateway))).initialize(payable(exocoreValidatorSet.addr));
vm.stopBroadcast();

vm.startBroadcast(exocoreValidatorSet.privateKey);
exocoreGateway.setPeer(clientChainId, address(clientGateway).toBytes32());
NonShortCircuitEndpointV2Mock(address(exocoreLzEndpoint)).setDestLzEndpoint(
address(clientGateway), address(clientChainLzEndpoint)
);
vm.stopBroadcast();
}
}
6 changes: 6 additions & 0 deletions script/testContracts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"exocore": {
"exocoreGateway": "0xbBd770D6288d03DfB2b87b6f88A049EC120647b7",
"lzEndpoint": "0x43B57f4fA1E4445296c133B1C3814655E2d77c35"
}
}
Loading

0 comments on commit b834259

Please sign in to comment.