Skip to content

Commit

Permalink
fix hexxens audit
Browse files Browse the repository at this point in the history
  • Loading branch information
invocamanman committed Jan 25, 2024
1 parent 21e926d commit 4368411
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 6 deletions.
3 changes: 2 additions & 1 deletion .solcover.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
module.exports = {
skipFiles: ['mocks', 'interfaces']
skipFiles: ['mocks/', 'interfaces/'],
configureYulOptimizer: true,
};
3 changes: 2 additions & 1 deletion contracts/v2/PolygonRollupManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ import "./lib/PolygonAccessControlUpgradeable.sol";
import "./lib/LegacyZKEVMStateVariables.sol";
import "./consensus/zkEVM/PolygonZkEVMV2Existent.sol";

// PolygonL2Manager, ?¿ TODO
/**
* Contract responsible for managing the exit roots across multiple Rollups
*/
contract PolygonRollupManager is
contract PolygonRollupManager is
PolygonAccessControlUpgradeable,
EmergencyManager,
LegacyZKEVMStateVariables,
Expand Down
8 changes: 5 additions & 3 deletions contracts/v2/PolygonZkEVMBridgeV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20Metadat
import "../lib/EmergencyManager.sol";
import "../lib/GlobalExitRootLib.sol";

// contract PolygonBridge is DepositContractV2, EmergencyManager, IPolygonBridge {
// TODO
/**
* PolygonZkEVMBridge that will be deployed on both networks Ethereum and Polygon zkEVM
* Contract responsible to manage the token interactions with other networks
Expand Down Expand Up @@ -105,9 +107,9 @@ contract PolygonZkEVMBridgeV2 is
polygonRollupManager = _polygonRollupManager;

// Set gas token
if (gasTokenAddress == address(0)) {
if (_gasTokenAddress == address(0)) {
// Gas token will be ether
if (gasTokenNetwork != 0) {
if (_gasTokenNetwork != 0) {
revert GasTokenNetworkMustBeZeroOnEther();
}
// WETHToken, gasTokenAddress and gasTokenNetwork will be 0
Expand Down Expand Up @@ -763,7 +765,7 @@ contract PolygonZkEVMBridgeV2 is
uint32 sourceBridgeNetwork;

// Get origin network from global index
if (globalIndex & _GLOBAL_INDEX_MAINNET_FLAG == 1) {
if (globalIndex & _GLOBAL_INDEX_MAINNET_FLAG != 0) {
// the network is mainnet, therefore sourceBridgeNetwork is 0

// Last 32 bits are leafIndex
Expand Down
2 changes: 2 additions & 0 deletions contracts/v2/PolygonZkEVMGlobalExitRootV2.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ pragma solidity 0.8.20;
import "../interfaces/IPolygonZkEVMGlobalExitRoot.sol";
import "../lib/GlobalExitRootLib.sol";

// TODO contract PolygonGlobalExitRootManager is IPolygonGlobalExitRootManager {

/**
* Contract responsible for managing the exit roots across multiple networks
*/
Expand Down
1 change: 1 addition & 0 deletions contracts/v2/lib/PolygonRollupBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import "../interfaces/IPolygonZkEVMBridgeV2.sol";
* The aggregators will be able to verify the sequenced state with zkProofs and therefore make available the withdrawals from L2 network.
* To enter and exit of the L2 network will be used a PolygonZkEVMBridge smart contract that will be deployed in both networks.
*/
// PolygonL2Base rename TODO
contract PolygonRollupBase is
Initializable,
IPolygonZkEVMV2Errors,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
"dockerv2:contracts": "sudo ./docker/scripts/v2/deploy-dockerv2.sh",
"push:docker:contracts": "docker push hermeznetwork/geth-zkevm-contracts",
"update:genesis": "node deployment/1_createGenesis.js && node deployment/1_createGenesis.js --test --input ../docker/scripts/deploy_parameters_docker.json --out ../docker/scripts/genesis_docker.json",
"coverage": "npx hardhat coverage",
"coverage": "npx hardhat coverage --testfiles \"test/contractsv2/*.ts\"",
"gas:report": "REPORT_GAS=true npx hardhat test",
"gas:report:file": "rm -f .openzeppelin/unknown-31337.json && REPORT_GAS=true REPORT_GAS_FILE=true npx hardhat test",
"deploy:v2:localhost": "rm -f .openzeppelin/unknown-31337.json && npx ts-node deployment/v2/1_createGenesis.ts --test && npx hardhat run deployment/v2/2_deployPolygonZKEVMDeployer.ts --network localhost && npx hardhat run deployment/v2/3_deployContracts.ts --network localhost && npx hardhat run deployment/v2/4_createRollup.ts --network localhost",
Expand Down
134 changes: 134 additions & 0 deletions test/contractsv2/BridgeV2.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,140 @@ describe("PolygonZkEVMBridge Contract", () => {
);
});

it("should claim tokens from Mainnet to Mainnet", async () => {
const originNetwork = networkIDMainnet;
const tokenAddress = polTokenContract.target;
const amount = ethers.parseEther("10");
const destinationNetwork = networkIDMainnet;
const destinationAddress = acc1.address;

const metadata = metadataToken;
const metadataHash = ethers.solidityPackedKeccak256(["bytes"], [metadata]);

const rollupExitRoot = await polygonZkEVMGlobalExitRoot.lastRollupExitRoot();

// compute root merkle tree in Js
const height = 32;
const merkleTreeLocal = new MerkleTreeBridge(height);
const leafValue = getLeafValue(
LEAF_TYPE_ASSET,
originNetwork,
tokenAddress,
destinationNetwork,
destinationAddress,
amount,
metadataHash
);
merkleTreeLocal.add(leafValue);

const mainnetExitRoot = merkleTreeLocal.getRoot();
const indexRollup = 0;

// check only rollup account with update rollup exit root
await expect(polygonZkEVMGlobalExitRoot.updateExitRoot(mainnetExitRoot)).to.be.revertedWithCustomError(
polygonZkEVMGlobalExitRoot,
"OnlyAllowedContracts"
);

// add rollup Merkle root
await ethers.provider.send("hardhat_impersonateAccount", [polygonZkEVMBridgeContract.target]);
const bridgemoCK = await ethers.getSigner(polygonZkEVMBridgeContract.target as any);

// await deployer.sendTransaction({
// to: bridgemoCK.address,
// value: ethers.parseEther("1"),
// });

await expect(polygonZkEVMGlobalExitRoot.connect(bridgemoCK).updateExitRoot(mainnetExitRoot, {gasPrice: 0}))
.to.emit(polygonZkEVMGlobalExitRoot, "UpdateGlobalExitRoot")
.withArgs(mainnetExitRoot, rollupExitRoot);

// check roots
const rollupExitRootSC = await polygonZkEVMGlobalExitRoot.lastRollupExitRoot();
expect(rollupExitRootSC).to.be.equal(rollupExitRoot);
const mainnetExitRootSC = await polygonZkEVMGlobalExitRoot.lastMainnetExitRoot();
expect(mainnetExitRootSC).to.be.equal(mainnetExitRoot);

const computedGlobalExitRoot = calculateGlobalExitRoot(mainnetExitRoot, rollupExitRootSC);
expect(computedGlobalExitRoot).to.be.equal(await polygonZkEVMGlobalExitRoot.getLastGlobalExitRoot());

// check merkle proof

// Merkle proof local
const indexLocal = 0;
const proofLocal = merkleTreeLocal.getProofTreeByIndex(indexLocal);

// verify merkle proof
expect(verifyMerkleProof(leafValue, proofLocal, indexLocal, mainnetExitRoot)).to.be.equal(true);

const globalIndex = computeGlobalIndex(indexLocal, indexRollup, true);

/*
* claim
* Can't claim without tokens
*/
await expect(
polygonZkEVMBridgeContract.claimAsset(
proofLocal,
proofLocal,
globalIndex,
mainnetExitRoot,
rollupExitRootSC,
originNetwork,
tokenAddress,
destinationNetwork,
destinationAddress,
amount,
metadata
)
).to.be.revertedWith("ERC20: transfer amount exceeds balance");

// transfer tokens, then claim
await expect(polTokenContract.transfer(polygonZkEVMBridgeContract.target, amount))
.to.emit(polTokenContract, "Transfer")
.withArgs(deployer.address, polygonZkEVMBridgeContract.target, amount);

expect(false).to.be.equal(await polygonZkEVMBridgeContract.isClaimed(indexLocal, indexRollup + 1));

await expect(
polygonZkEVMBridgeContract.claimAsset(
proofLocal,
proofLocal,
globalIndex,
mainnetExitRoot,
rollupExitRootSC,
originNetwork,
tokenAddress,
destinationNetwork,
destinationAddress,
amount,
metadata
)
)
.to.emit(polygonZkEVMBridgeContract, "ClaimEvent")
.withArgs(globalIndex, originNetwork, tokenAddress, destinationAddress, amount)
.to.emit(polTokenContract, "Transfer")
.withArgs(polygonZkEVMBridgeContract.target, acc1.address, amount);

// Can't claim because nullifier
await expect(
polygonZkEVMBridgeContract.claimAsset(
proofLocal,
proofLocal,
globalIndex,
mainnetExitRoot,
rollupExitRootSC,
originNetwork,
tokenAddress,
destinationNetwork,
destinationAddress,
amount,
metadata
)
).to.be.revertedWithCustomError(polygonZkEVMBridgeContract, "AlreadyClaimed");
expect(true).to.be.equal(await polygonZkEVMBridgeContract.isClaimed(indexLocal, indexRollup + 1));
});

it("should claim tokens from Mainnet to Mainnet", async () => {
const originNetwork = networkIDMainnet;
const tokenAddress = polTokenContract.target;
Expand Down

0 comments on commit 4368411

Please sign in to comment.