Skip to content

Commit f7c2511

Browse files
committed
More updates post-review
1 parent 3782567 commit f7c2511

File tree

7 files changed

+59
-52
lines changed

7 files changed

+59
-52
lines changed

contracts/bridging/WormholeBridgeForColony.sol

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ pragma solidity 0.8.23;
2121
import { IWormhole } from "../../lib/wormhole/ethereum/contracts/interfaces/IWormhole.sol";
2222
import { IColonyNetwork } from "../colonyNetwork/IColonyNetwork.sol";
2323
import { IColonyBridge } from "./IColonyBridge.sol";
24+
import { CallWithGuards } from "../common/CallWithGuards.sol";
2425
import { DSAuth } from "../../lib/dappsys/auth.sol";
2526

26-
contract WormholeBridgeForColony is DSAuth, IColonyBridge {
27+
contract WormholeBridgeForColony is DSAuth, IColonyBridge, CallWithGuards {
2728
address colonyNetwork;
2829
// ChainId => colonyBridge
2930
mapping(uint256 => address) colonyBridges;
@@ -100,22 +101,15 @@ contract WormholeBridgeForColony is DSAuth, IColonyBridge {
100101

101102
// Do the thing
102103

103-
(bool success, bytes memory returndata) = address(colonyNetwork).call(wormholeMessage.payload);
104+
(bool success, bytes memory returndata) = callWithGuards(
105+
colonyNetwork,
106+
wormholeMessage.payload
107+
);
108+
// Note that this is not a require because returndata might not be a string, and if we try
109+
// to decode it we'll get a revert.
104110
if (!success) {
105-
// Stolen shamelessly from
106-
// https://ethereum.stackexchange.com/questions/83528/how-can-i-get-the-revert-reason-of-a-call-in-solidity-so-that-i-can-use-it-in-th
107-
// If the _res length is less than 68, then the transaction failed silently (without a revert message)
108-
if (returndata.length >= 68) {
109-
assembly {
110-
// Slice the sighash.
111-
returndata := add(returndata, 0x04)
112-
}
113-
require(false, abi.decode(returndata, (string))); // All that remains is the revert string
114-
}
115-
require(false, "require-execute-call-reverted-with-no-error");
111+
revert(abi.decode(returndata, (string)));
116112
}
117-
118-
require(success, "wormhole-bridge-receive-message-failed");
119113
}
120114

121115
function sendMessage(
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
pragma solidity 0.8.23;
2+
3+
contract CallWithGuards {
4+
function isContract(address addr) internal view returns (bool) {
5+
uint256 size;
6+
assembly {
7+
size := extcodesize(addr)
8+
}
9+
return size > 0;
10+
}
11+
12+
function callWithGuards(
13+
address _target,
14+
bytes memory _payload
15+
) internal returns (bool, bytes memory) {
16+
if (!isContract(_target)) {
17+
return (false, abi.encode("require-execute-call-target-not-contract"));
18+
}
19+
(bool success, bytes memory returndata) = address(_target).call(_payload);
20+
if (!success) {
21+
// Stolen shamelessly from
22+
// https://ethereum.stackexchange.com/questions/83528/how-can-i-get-the-revert-reason-of-a-call-in-solidity-so-that-i-can-use-it-in-th
23+
// If the _res length is less than 68, then the transaction failed silently (without a revert message)
24+
if (returndata.length >= 68) {
25+
assembly {
26+
// Slice the sighash.
27+
returndata := add(returndata, 0x04)
28+
}
29+
return (false, returndata); // All that remains is the revert string
30+
}
31+
return (false, abi.encode("require-execute-call-reverted-with-no-error"));
32+
}
33+
return (success, returndata);
34+
}
35+
}

contracts/testHelpers/RequireExecuteCall.sol

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,11 @@
1919
pragma solidity 0.8.23;
2020
pragma experimental ABIEncoderV2;
2121

22-
contract RequireExecuteCall {
22+
import { CallWithGuards } from "./../common/CallWithGuards.sol";
23+
24+
contract RequireExecuteCall is CallWithGuards {
2325
function executeCall(address target, bytes memory action) public {
24-
bool success;
25-
bytes memory returndata;
26-
(success, returndata) = target.call(action);
27-
if (!success) {
28-
// Stolen shamelessly from
29-
// https://ethereum.stackexchange.com/questions/83528/how-can-i-get-the-revert-reason-of-a-call-in-solidity-so-that-i-can-use-it-in-th
30-
// If the _res length is less than 68, then the transaction failed silently (without a revert message)
31-
if (returndata.length >= 68) {
32-
assembly {
33-
// Slice the sighash.
34-
returndata := add(returndata, 0x04)
35-
}
36-
require(false, abi.decode(returndata, (string))); // All that remains is the revert string
37-
}
38-
require(false, "require-execute-call-reverted-with-no-error");
39-
}
26+
(bool success, bytes memory returndata) = callWithGuards(target, action);
27+
require(success, abi.decode(returndata, (string)));
4028
}
4129
}

hardhat.config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
const { FORKED_XDAI_CHAINID } = require("./helpers/constants");
2+
13
module.exports = {
24
defaultNetwork: "hardhat",
35
solidity: {
@@ -15,7 +17,7 @@ module.exports = {
1517
},
1618
networks: {
1719
hardhat: {
18-
chainId: 265669100,
20+
chainId: FORKED_XDAI_CHAINID,
1921
throwOnCallFailures: false,
2022
throwOnTransactionFailures: false,
2123
blockGasLimit: 6721975,

helpers/test-helper.js

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -431,12 +431,7 @@ exports.expectAllEvents = async function expectAllEvents(tx, eventNames) {
431431
};
432432

433433
exports.forwardTime = async function forwardTime(seconds, test, _web3provider) {
434-
let web3provider;
435-
if (!_web3provider) {
436-
web3provider = web3.currentProvider;
437-
} else {
438-
web3provider = _web3provider;
439-
}
434+
const web3provider = _web3provider || web3.currentProvider;
440435
if (typeof seconds !== "number") {
441436
throw new Error("typeof seconds is not a number");
442437
}
@@ -1247,14 +1242,7 @@ exports.sleep = function sleep(ms) {
12471242
};
12481243

12491244
exports.upgradeColonyTo = async function (colony, _version) {
1250-
let version = _version;
1251-
if (!BN.isBN(_version)) {
1252-
try {
1253-
version = new BN(_version);
1254-
} catch (err) {
1255-
console.log("Unable to convert passed version to BN");
1256-
}
1257-
}
1245+
const version = new BN(_version);
12581246
let currentVersion = await colony.version();
12591247
while (currentVersion.ltn(version)) {
12601248
await colony.upgrade(currentVersion.addn(1));

scripts/mockBridgeMonitor.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ class MockBridgeMonitor {
4545
});
4646
}
4747

48+
// VAAs are the primitives used on wormhole (Verified Action Approvals)
49+
// See https://docs.wormhole.com/wormhole/explore-wormhole/vaa for more details
50+
// Note that the documentation sometimes also calls them VMs (as does IWormhole)
51+
// I believe VM stands for 'Verified Message'
4852
async encodeMockVAA(sender, sequence, nonce, payload, consistencyLevel, chainId) {
4953
const version = 1;
5054
const timestamp = Math.floor(Date.now() / 1000);

test/contracts-network/colony-network.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -507,11 +507,7 @@ contract("Colony Network", (accounts) => {
507507
let suffix;
508508

509509
before(async () => {
510-
if (await isXdai()) {
511-
suffix = "colonyxdai";
512-
} else {
513-
suffix = "eth";
514-
}
510+
suffix = (await isXdai()) ? "colonyxdai" : "eth";
515511
});
516512

517513
beforeEach(async () => {

0 commit comments

Comments
 (0)