Skip to content

Commit

Permalink
Merge pull request #44 from delegatable/passthrough-errors
Browse files Browse the repository at this point in the history
Passthrough errors
  • Loading branch information
danfinlay authored Dec 17, 2022
2 parents 938879a + 3d4470d commit fb34bb2
Show file tree
Hide file tree
Showing 5 changed files with 10,059 additions and 10,660 deletions.
29 changes: 28 additions & 1 deletion contracts/DelegatableCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,35 @@ abstract contract DelegatableCore is EIP712Decoder {
address sender
) internal returns (bool success) {
bytes memory full = abi.encodePacked(data, sender);
bytes memory errorMessage;
(success, errorMessage) = address(to).call{gas: gasLimit}(full);

if (!success) {
if (errorMessage.length > 0) {
string memory reason = extractRevertReason(errorMessage);
revert(reason);
} else {
revert("DelegatableCore::execution-failed");
}
}
}

function extractRevertReason(bytes memory revertData)
internal
pure
returns (string memory reason)
{
uint256 l = revertData.length;
if (l < 68) return "";
uint256 t;
assembly {
revertData := add(revertData, 4)
t := mload(revertData) // Save the content of the length slot
mstore(revertData, sub(l, 4)) // Set proper length
}
reason = abi.decode(revertData, (string));
assembly {
success := call(gasLimit, to, 0, add(full, 0x20), mload(full), 0, 0)
mstore(revertData, t) // Restore the content of the length slot
}
}

Expand Down
30 changes: 29 additions & 1 deletion contracts/DelegatableRelayCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,43 @@ abstract contract DelegatableRelayCore is EIP712Decoder {
multiNonce[intendedSender][queue] = nonce;
}


function _execute(
address to,
bytes memory data,
uint256 gasLimit,
address sender
) internal returns (bool success) {
bytes memory full = abi.encodePacked(data, sender);
bytes memory errorMessage;
(success, errorMessage) = address(to).call{gas: gasLimit}(full);

if (!success) {
if (errorMessage.length > 0) {
string memory reason = extractRevertReason(errorMessage);
revert(reason);
} else {
revert("DelegatableCore::execution-failed");
}
}
}

function extractRevertReason(bytes memory revertData)
internal
pure
returns (string memory reason)
{
uint256 l = revertData.length;
if (l < 68) return "";
uint256 t;
assembly {
revertData := add(revertData, 4)
t := mload(revertData) // Save the content of the length slot
mstore(revertData, sub(l, 4)) // Set proper length
}
reason = abi.decode(revertData, (string));
assembly {
success := call(gasLimit, to, 0, add(full, 0x20), mload(full), 0, 0)
mstore(revertData, t) // Restore the content of the length slot
}
}

Expand Down
4 changes: 4 additions & 0 deletions contracts/mock/MockDelegatable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ contract MockDelegatable is Delegatable, Ownable {
purpose = purpose_;
}

function alwaysFail() public pure {
revert("I always fail");
}

function _msgSender()
internal
view
Expand Down
29 changes: 29 additions & 0 deletions test/Delegatable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,35 @@ describe("Delegatable", () => {
"0xf6e94ae88b8b72d51444924d7cf26f28b4eaf7d5d274dffbdc83cb92cb4eeac5"
);
});

it("INVOKE alwaysFail() bubbles out error", async () => {
const INVOCATION_MESSAGE = {
replayProtection: {
nonce: "0x01",
queue: "0x00",
},
batch: [
{
authority: [],
transaction: {
to: Delegatable.address,
gasLimit: "21000000000000",
data: (await Delegatable.populateTransaction.alwaysFail()).data,
},
},
],
};
const invocation = delegatableUtils.signInvocation(INVOCATION_MESSAGE, pk0);
await expect(
Delegatable.invoke([
{
signature: invocation.signature,
invocations: invocation.invocations,
},
])
).to.be.revertedWith("I always fail");
});

it("READ getEIP712DomainHash(string,string,uint256,address)", async () => {});
it("READ verifyDelegationSignature(SignedDelegation memory signedDelegation)`", async () => {
const _delegation = generateDelegation(
Expand Down
Loading

0 comments on commit fb34bb2

Please sign in to comment.