Skip to content

Commit

Permalink
feat: add sendAndCallEnabled boolean and overrides sendAndCall functi…
Browse files Browse the repository at this point in the history
…on of layerZero
  • Loading branch information
GitGuru7 committed Dec 14, 2023
1 parent 3c55e8f commit 93802df
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 0 deletions.
37 changes: 37 additions & 0 deletions contracts/Bridge/BaseXVSProxyOFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ abstract contract BaseXVSProxyOFT is Pausable, ExponentialNoError, BaseOFTV2 {
using SafeERC20 for IERC20;
IERC20 internal immutable innerToken;

Check warning on line 24 in contracts/Bridge/BaseXVSProxyOFT.sol

View workflow job for this annotation

GitHub Actions / Lint

Immutable variables name are set to be in capitalized SNAKE_CASE
uint256 internal immutable ld2sdRate;

Check warning on line 25 in contracts/Bridge/BaseXVSProxyOFT.sol

View workflow job for this annotation

GitHub Actions / Lint

Immutable variables name are set to be in capitalized SNAKE_CASE
bool public sendAndCallEnabled;

/**
* @notice The address of ResilientOracle contract wrapped in its interface.
Expand Down Expand Up @@ -238,6 +239,42 @@ abstract contract BaseXVSProxyOFT is Pausable, ExponentialNoError, BaseOFTV2 {
emit TrustedRemoteRemoved(remoteChainId_);
}

/**
* @notice It enables or disables sendAndCall functionality for the bridge.
* @param enabled_ Boolean indicating whether the sendAndCall function should be enabled or disabled.
*/
function updateSendAndCallEnabled(bool enabled_) external onlyOwner {
sendAndCallEnabled = enabled_;
}

/**
* @notice Initiates a cross-chain token transfer and triggers a call on the destination chain.
* @dev This internal override function enables the contract to send tokens and invoke calls on the specified
* destination chain. It checks whether the sendAndCall feature is enabled before proceeding with the transfer.
* @param from_ Address from which tokens will be debited.
* @param dstChainId_ Destination chain id on which tokens will be send.
* @param toAddress_ Address on which tokens will be credited on destination chain.
* @param amount_ Amount of tokens that will be transferred.
* @param payload_ Additional data payload for the call on the destination chain.
* @param dstGasForCall_ The amount of gas allocated for the call on the destination chain.
* @param callparams_ Additional parameters, including refund address, ZRO payment address,
* and adapter params.
*/

function sendAndCall(
address from_,
uint16 dstChainId_,
bytes32 toAddress_,
uint256 amount_,
bytes calldata payload_,
uint64 dstGasForCall_,
LzCallParams calldata callparams_
) public payable override {
require(sendAndCallEnabled, "sendAndCall is disabled");

Check warning on line 273 in contracts/Bridge/BaseXVSProxyOFT.sol

View workflow job for this annotation

GitHub Actions / Lint

Use Custom Errors instead of require statements

super.sendAndCall(from_, dstChainId_, toAddress_, amount_, payload_, dstGasForCall_, callparams_);
}

/**
* @notice Empty implementation of renounce ownership to avoid any mishappening.
*/
Expand Down
62 changes: 62 additions & 0 deletions test/proxyOFT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ describe("Proxy OFTV2: ", function () {
"setPayloadSizeLimit(uint16,uint256)",
"setUseCustomAdapterParams(bool)",
"removeTrustedRemote(uint16)",
"updateSendAndCallEnabled(bool)",
];
const activeArray = new Array(functionregistry.length).fill(true);
await bridgeAdminRemote.upsertSignature(functionregistry, activeArray);
Expand Down Expand Up @@ -718,4 +719,65 @@ describe("Proxy OFTV2: ", function () {
});
expect(await localOFT.trustedRemoteLookup(remoteChainId)).equals("0x");
});
it("Reverts when sendAndCall is disabled", async function () {
const amount = ethers.utils.parseEther("2", 18);
const dstGasForCall_ = 0;
const uint160Value = BigInt("0x" + acc3.address.slice(2));
const bytes32Value = uint160Value << BigInt(96);
const acc3AddressBytes32 = "0x" + bytes32Value.toString(16).padStart(32, "0");

await expect(
localOFT
.connect(acc1)
.sendAndCall(acc3.address, remoteChainId, acc3AddressBytes32, amount, "0x", dstGasForCall_, [
acc1.address,
acc1.address,
"0x",
]),
).to.be.revertedWith("sendAndCall is disabled");
});

it("Successfully call sendAndCall", async function () {
const uint160Value = BigInt("0x" + acc3.address.slice(2));
const bytes32Value = uint160Value << BigInt(96);
const acc3AddressBytes32 = "0x" + bytes32Value.toString(16).padStart(32, "0");
let data = localOFT.interface.encodeFunctionData("setMinDstGas", [remoteChainId, 1, 300000]);
const amount = ethers.utils.parseEther("2", 18);
const dstGasForCall_ = 0;
await acc1.sendTransaction({
to: bridgeAdminLocal.address,
data: data,
});

await acc1.sendTransaction({
to: bridgeAdminLocal.address,
data: data,
});
data = localOFT.interface.encodeFunctionData("updateSendAndCallEnabled", [true]);
await acc1.sendTransaction({
to: bridgeAdminLocal.address,
data: data,
});

const adapterParams = ethers.utils.solidityPack(["uint16", "uint256"], [1, 300000]);
await localToken.connect(acc1).faucet(amount);
await localToken.connect(acc1).approve(localOFT.address, amount);
expect(await localOFT.sendAndCallEnabled()).to.be.true;

const nativeFee = (await localOFT.estimateSendFee(remoteChainId, acc3AddressBytes32, amount, false, adapterParams))
.nativeFee;

await localOFT
.connect(acc1)
.sendAndCall(
acc1.address,
remoteChainId,
acc3AddressBytes32,
amount,
"0x",
dstGasForCall_,
[acc1.address, acc1.address, adapterParams],
{ value: nativeFee },
);
});
});

0 comments on commit 93802df

Please sign in to comment.