-
Notifications
You must be signed in to change notification settings - Fork 49
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: check withdraw fee in Swap, callMulti example, universal NFT/FT #229
base: main
Are you sure you want to change the base?
Changes from all commits
c7ba7e5
142c36c
926a9f9
d07edd7
05d2288
272329d
21cd7be
c0a77f4
63b4a4b
de77a5f
4799aec
c181622
947d450
81325b3
a34b866
d8732f7
0272470
468bece
846d720
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -41,6 +41,36 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gateway.call(receiver, zrc20, message, callOptions, revertOptions); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
function callMulti( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bytes[] memory receiverArray, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
address[] memory zrc20Array, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bytes calldata messages, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
CallOptions memory callOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
RevertOptions memory revertOptions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) external { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
for (uint256 i = 0; i < zrc20Array.length; i++) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
(, uint256 gasFee) = IZRC20(zrc20Array[i]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.withdrawGasFeeWithGasLimit(callOptions.gasLimit); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
!IZRC20(zrc20Array[i]).transferFrom( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
msg.sender, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
address(this), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gasFee | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
revert TransferFailed(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
IZRC20(zrc20Array[i]).approve(address(gateway), gasFee); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
gateway.call( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
receiverArray[i], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
zrc20Array[i], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
messages, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
callOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
revertOptions | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+44
to
+72
Check warning Code scanning / Slither Unused return Medium
Comment on lines
+44
to
+72
Check notice Code scanning / Slither Calls inside a loop Low
Comment on lines
+44
to
+72
Check notice Code scanning / Slither Calls inside a loop Low
Comment on lines
+44
to
+72
Check notice Code scanning / Slither Calls inside a loop Low
Universal.callMulti(bytes[],address[],bytes,CallOptions,RevertOptions) has external calls inside a loop: ! IZRC20(zrc20Array[i]).transferFrom(msg.sender,address(this),gasFee)
Comment on lines
+44
to
+72
Check notice Code scanning / Slither Calls inside a loop Low
Universal.callMulti(bytes[],address[],bytes,CallOptions,RevertOptions) has external calls inside a loop: IZRC20(zrc20Array[i]).approve(address(gateway),gasFee)
Comment on lines
+44
to
+72
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Address potential security and gas optimization concerns in the multi-call implementation. The current implementation has several areas that need attention:
Consider implementing these improvements: function callMulti(
bytes[] memory receiverArray,
address[] memory zrc20Array,
bytes calldata messages,
CallOptions memory callOptions,
RevertOptions memory revertOptions
) external {
+ if (receiverArray.length != zrc20Array.length) {
+ revert("Array lengths mismatch");
+ }
+ if (receiverArray.length == 0) {
+ revert("Empty arrays");
+ }
+ if (receiverArray.length > 10) { // Adjust limit based on gas considerations
+ revert("Too many calls");
+ }
+
+ uint256[] memory gasFees = new uint256[](zrc20Array.length);
+ // Batch all checks first
+ for (uint256 i = 0; i < zrc20Array.length; i++) {
+ (, gasFees[i]) = IZRC20(zrc20Array[i])
+ .withdrawGasFeeWithGasLimit(callOptions.gasLimit);
+ if (!IZRC20(zrc20Array[i]).transferFrom(
+ msg.sender,
+ address(this),
+ gasFees[i]
+ )) {
+ revert TransferFailed();
+ }
+ }
+
+ // Then batch all approvals and calls
+ for (uint256 i = 0; i < zrc20Array.length; i++) {
+ IZRC20(zrc20Array[i]).approve(address(gateway), gasFees[i]);
gateway.call(
receiverArray[i],
zrc20Array[i],
messages,
callOptions,
revertOptions
);
}
} 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Check: Slither[warning] 44-72: Unused return [warning] 44-72: Unused return [notice] 44-72: Calls inside a loop [notice] 44-72: Calls inside a loop [notice] 44-72: Calls inside a loop [notice] 44-72: Calls inside a loop |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
function withdraw( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bytes memory receiver, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
uint256 amount, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,22 +1,16 @@ | ||||||||||||||||||||||||||||||||||
import "./tasks/deploy"; | ||||||||||||||||||||||||||||||||||
import "./tasks/universalCall"; | ||||||||||||||||||||||||||||||||||
import "./tasks/connectedCall"; | ||||||||||||||||||||||||||||||||||
import "./tasks/connectedDeposit"; | ||||||||||||||||||||||||||||||||||
import "./tasks/connectedDepositAndCall"; | ||||||||||||||||||||||||||||||||||
import "./tasks/universalWithdraw"; | ||||||||||||||||||||||||||||||||||
import "./tasks/universalWithdrawAndCall"; | ||||||||||||||||||||||||||||||||||
import "@zetachain/localnet/tasks"; | ||||||||||||||||||||||||||||||||||
import "@nomicfoundation/hardhat-toolbox"; | ||||||||||||||||||||||||||||||||||
import { HardhatUserConfig } from "hardhat/config"; | ||||||||||||||||||||||||||||||||||
import * as dotenv from "dotenv"; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
import "./tasks"; | ||||||||||||||||||||||||||||||||||
import "@zetachain/localnet/tasks"; | ||||||||||||||||||||||||||||||||||
import "@zetachain/toolkit/tasks"; | ||||||||||||||||||||||||||||||||||
import { getHardhatConfig } from "@zetachain/toolkit/client"; | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
import { getHardhatConfigNetworks } from "@zetachain/networks"; | ||||||||||||||||||||||||||||||||||
import { HardhatUserConfig } from "hardhat/config"; | ||||||||||||||||||||||||||||||||||
dotenv.config(); | ||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
const config: HardhatUserConfig = { | ||||||||||||||||||||||||||||||||||
networks: { | ||||||||||||||||||||||||||||||||||
...getHardhatConfigNetworks(), | ||||||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||||||
solidity: "0.8.26", | ||||||||||||||||||||||||||||||||||
...getHardhatConfig({ accounts: [process.env.PRIVATE_KEY] }), | ||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||
Comment on lines
+10
to
+13
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Enhance environment variable validation. The configuration directly uses Add this validation before the config: dotenv.config();
+if (!process.env.PRIVATE_KEY) {
+ throw new Error("PRIVATE_KEY environment variable is required");
+}
+
const config: HardhatUserConfig = { 📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: Run Tests[error] Compiler configuration needs to be updated to support Solidity versions 0.8.20, 0.8.21, and 0.8.26 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add compiler configuration to resolve pipeline failures. The pipeline is failing due to missing Solidity compiler configuration. Add the compiler settings to support the required versions. Apply this diff to resolve the compiler configuration: const config: HardhatUserConfig = {
...getHardhatConfig({ accounts: [process.env.PRIVATE_KEY] }),
+ solidity: {
+ version: "0.8.21",
+ settings: {
+ optimizer: {
+ enabled: true,
+ runs: 200,
+ },
+ },
+ },
};
🧰 Tools🪛 GitHub Actions: Run Tests[error] Compiler configuration needs to be updated to support Solidity versions 0.8.20, 0.8.21, and 0.8.26 |
||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||
export default config; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,7 +29,7 @@ | |
"@typescript-eslint/eslint-plugin": "^5.59.9", | ||
"@typescript-eslint/parser": "^5.59.9", | ||
"@zetachain/localnet": "4.0.0-rc6", | ||
"@zetachain/toolkit": "13.0.0-rc7", | ||
"@zetachain/toolkit": "13.0.0-rc13", | ||
"axios": "^1.3.6", | ||
"chai": "^4.2.0", | ||
"dotenv": "^16.0.3", | ||
|
@@ -57,6 +57,8 @@ | |
"@solana-developers/helpers": "^2.4.0", | ||
"@solana/spl-memo": "^0.2.5", | ||
"@solana/web3.js": "^1.95.8", | ||
"@zetachain/protocol-contracts": "11.0.0-rc3" | ||
"@zetachain/networks": "10.0.0-rc4", | ||
"@zetachain/protocol-contracts": "11.0.0-rc3", | ||
"@zetachain/protocol-contracts-solana": "2.0.0-rc1" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Remove or document unused Solana dependency The
🔗 Analysis chainVerify Solana contract integration requirements. The addition of Run this script to check for Solana-related configuration and documentation: 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Check for Solana configuration and documentation
# Check for Solana configuration files
echo "Checking for Solana configuration files:"
fd -e yaml -e json "solana" examples/call/
# Check for Solana documentation
echo -e "\nChecking for Solana documentation:"
rg -i "solana" examples/call/README.md || echo "No Solana documentation found in README"
Length of output: 346 Script: #!/bin/bash
# Check for imports and usage of Solana contracts
echo "Checking for Solana contract imports and usage:"
rg -i "@zetachain/protocol-contracts-solana" examples/call/ -A 2
echo -e "\nChecking for Solana-related code patterns:"
rg -i "solana" examples/call/ --type ts --type js --type tsx --type jsx
Length of output: 1163 |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import "./deploy"; | ||
import "./universalCall"; | ||
import "./universalCallMulti"; | ||
import "./connectedCall"; | ||
import "./connectedDeposit"; | ||
import "./connectedDepositAndCall"; | ||
import "./universalWithdraw"; | ||
import "./universalWithdrawAndCall"; |
Check warning
Code scanning / Slither
Unused return Medium