Skip to content

Commit

Permalink
feat: delegate call with ens
Browse files Browse the repository at this point in the history
  • Loading branch information
ZzzzHui committed May 6, 2024
1 parent 5559379 commit 472eb80
Show file tree
Hide file tree
Showing 8 changed files with 730 additions and 187 deletions.
6 changes: 6 additions & 0 deletions .changeset/olive-crabs-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@cartesi/rollups": major
---

Added contract `AssetTransferToENS` that can be used as a destination for `DELEGATECALL` vouchers to transfer assets to ENS-identified accounts.
Added library `LibAddress` for safe low level call and safe delegate call.
22 changes: 4 additions & 18 deletions contracts/dapp/Application.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {LibOutputValidityProof} from "../library/LibOutputValidityProof.sol";
import {OutputValidityProof} from "../common/OutputValidityProof.sol";
import {Outputs} from "../common/Outputs.sol";
import {InputRange} from "../common/InputRange.sol";
import {LibError} from "../library/LibError.sol";
import {LibInputRange} from "../library/LibInputRange.sol";
import {LibAddress} from "../library/LibAddress.sol";

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ERC721Holder} from "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
Expand All @@ -30,7 +30,7 @@ contract Application is
ReentrancyGuard
{
using BitMaps for BitMaps.BitMap;
using LibError for bytes;
using LibAddress for address;
using LibOutputValidityProof for OutputValidityProof;
using LibInputRange for InputRange;

Expand Down Expand Up @@ -203,14 +203,7 @@ contract Application is
(address, uint256, bytes)
);

bool success;
bytes memory returndata;

(success, returndata) = destination.call{value: value}(payload);

if (!success) {
returndata.raise();
}
destination.safeCall(value, payload);
}

/// @notice Executes a delegatecall voucher
Expand All @@ -221,13 +214,6 @@ contract Application is

(destination, payload) = abi.decode(arguments, (address, bytes));

bool success;
bytes memory returndata;

(success, returndata) = destination.delegatecall(payload);

if (!success) {
returndata.raise();
}
destination.safeDelegateCall(payload);
}
}
86 changes: 86 additions & 0 deletions contracts/delegatecall/AssetTransferToENS.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

pragma solidity ^0.8.20;

import {ENS} from "@ensdomains/ens-contracts/contracts/registry/ENS.sol";
import {AddrResolver} from "@ensdomains/ens-contracts/contracts/resolvers/profiles/AddrResolver.sol";

import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import {IERC1155} from "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";

import {LibAddress} from "../library/LibAddress.sol";

contract AssetTransferToENS {
using LibAddress for address;
using SafeERC20 for IERC20;

ENS immutable _ens;

constructor(ENS ens) {
_ens = ens;
}

function sendEtherToENS(
bytes32 node,
uint256 value,
bytes memory payload
) external {
address recipient = _resolveENS(node);
recipient.safeCall(value, payload);
}

function sendERC20ToENS(
IERC20 token,
bytes32 node,
uint256 value
) external {
address recipient = _resolveENS(node);
token.safeTransfer(recipient, value);
}

function sendERC721ToENS(
IERC721 token,
bytes32 node,
uint256 tokenId,
bytes calldata data
) external {
address recipient = _resolveENS(node);
token.safeTransferFrom(address(this), recipient, tokenId, data);
}

function sendERC1155ToENS(
IERC1155 token,
bytes32 node,
uint256 id,
uint256 value,
bytes calldata data
) external {
address recipient = _resolveENS(node);
token.safeTransferFrom(address(this), recipient, id, value, data);
}

function sendBatchERC1155ToENS(
IERC1155 token,
bytes32 node,
uint256[] memory ids,
uint256[] memory values,
bytes calldata data
) external {
address recipient = _resolveENS(node);
token.safeBatchTransferFrom(
address(this),
recipient,
ids,
values,
data
);
}

function _resolveENS(bytes32 node) internal view returns (address) {
AddrResolver resolver = AddrResolver(_ens.resolver(node));
return resolver.addr(node);
}
}
48 changes: 48 additions & 0 deletions contracts/library/LibAddress.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// (c) Cartesi and individual authors (see AUTHORS)
// SPDX-License-Identifier: Apache-2.0 (see LICENSE)

pragma solidity ^0.8.8;

import {LibError} from "../library/LibError.sol";

library LibAddress {
using LibError for bytes;

/// @notice Perform a low level call and raise error if failed
/// @param destination The address that will be called
/// @param value The amount of Wei to be transferred through the call
/// @param payload The payload, which—in the case of Solidity
/// contracts—encodes a function call
function safeCall(
address destination,
uint256 value,
bytes memory payload
) internal {
bool success;
bytes memory returndata;

(success, returndata) = destination.call{value: value}(payload);

if (!success) {
returndata.raise();
}
}

/// @notice Perform a delegate call and raise error if failed
/// @param destination The address that will be called
/// @param payload The payload, which—in the case of Solidity
/// libraries—encodes a function call
function safeDelegateCall(
address destination,
bytes memory payload
) internal {
bool success;
bytes memory returndata;

(success, returndata) = destination.delegatecall(payload);

if (!success) {
returndata.raise();
}
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@
},
"dependencies": {
"@cartesi/util": "6.1.0",
"@openzeppelin/contracts": "5.0.2"
"@openzeppelin/contracts": "5.0.2",
"@ensdomains/ens-contracts": "1.1.4"
},
"devDependencies": {
"@changesets/cli": "^2.27.1",
Expand Down
41 changes: 41 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 472eb80

Please sign in to comment.