Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Commit

Permalink
Assets V2 (paritytech#562)
Browse files Browse the repository at this point in the history
Co-authored-by: sumitsnk <[email protected]>
  • Loading branch information
vgeddes and sumitsnk authored Feb 3, 2022
1 parent 3e9d547 commit f27b762
Show file tree
Hide file tree
Showing 74 changed files with 1,678 additions and 1,467 deletions.
65 changes: 47 additions & 18 deletions ethereum/contracts/ERC20App.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "./ScaleCodec.sol";
import "./OutboundChannel.sol";

Expand All @@ -14,29 +15,33 @@ enum ChannelId {
}

contract ERC20App is AccessControl {
using ScaleCodec for uint256;
using ScaleCodec for uint128;
using ScaleCodec for uint32;
using ScaleCodec for uint8;
using SafeERC20 for IERC20;

mapping(address => uint256) public balances;
mapping(address => uint128) public balances;

mapping(ChannelId => Channel) public channels;

bytes2 constant MINT_CALL = 0x4201;
bytes2 constant CREATE_CALL = 0x4202;

mapping(address => bool) public tokens;

event Locked(
address token,
address sender,
bytes32 recipient,
uint256 amount,
uint128 amount,
uint32 paraId
);

event Unlocked(
address token,
bytes32 sender,
address recipient,
uint256 amount
uint128 amount
);

event Upgraded(
Expand Down Expand Up @@ -76,7 +81,7 @@ contract ERC20App is AccessControl {
function lock(
address _token,
bytes32 _recipient,
uint256 _amount,
uint128 _amount,
ChannelId _channelId,
uint32 _paraId
) public {
Expand All @@ -85,21 +90,33 @@ contract ERC20App is AccessControl {
_channelId == ChannelId.Incentivized,
"Invalid channel ID"
);

balances[_token] = balances[_token] + _amount;

emit Locked(_token, msg.sender, _recipient, _amount, _paraId);

OutboundChannel channel = OutboundChannel(
channels[_channelId].outbound
);

if (!tokens[_token]) {
bytes memory createCall = encodeCreateTokenCall(_token);
tokens[_token] = true;
channel.submit(msg.sender, createCall);
}

bytes memory call;
if(_paraId == 0) {
if (_paraId == 0) {
call = encodeCall(_token, msg.sender, _recipient, _amount);
} else {
call = encodeCallWithParaId(_token, msg.sender, _recipient, _amount, _paraId);
call = encodeCallWithParaId(
_token,
msg.sender,
_recipient,
_amount,
_paraId
);
}

OutboundChannel channel = OutboundChannel(
channels[_channelId].outbound
);
channel.submit(msg.sender, call);

require(
Expand All @@ -112,7 +129,7 @@ contract ERC20App is AccessControl {
address _token,
bytes32 _sender,
address _recipient,
uint256 _amount
uint128 _amount
) public onlyRole(INBOUND_CHANNEL_ROLE) {
require(_amount > 0, "Must unlock a positive amount");
require(
Expand All @@ -130,15 +147,16 @@ contract ERC20App is AccessControl {
address _token,
address _sender,
bytes32 _recipient,
uint256 _amount
uint128 _amount
) private pure returns (bytes memory) {
return abi.encodePacked(
return
abi.encodePacked(
MINT_CALL,
_token,
_sender,
bytes1(0x00), // Encode recipient as MultiAddress::Id
_recipient,
_amount.encode256(),
_amount.encode128(),
bytes1(0x00)
);
}
Expand All @@ -148,21 +166,32 @@ contract ERC20App is AccessControl {
address _token,
address _sender,
bytes32 _recipient,
uint256 _amount,
uint128 _amount,
uint32 _paraId
) private pure returns (bytes memory) {
return abi.encodePacked(
return
abi.encodePacked(
MINT_CALL,
_token,
_sender,
bytes1(0x00), // Encode recipient as MultiAddress::Id
_recipient,
_amount.encode256(),
_amount.encode128(),
bytes1(0x01),
_paraId.encode32()
);
}

function encodeCreateTokenCall(
address _token
) private pure returns (bytes memory) {
return
abi.encodePacked(
CREATE_CALL,
_token
);
}

function upgrade(
Channel memory _basic,
Channel memory _incentivized
Expand Down
46 changes: 22 additions & 24 deletions ethereum/contracts/ETHApp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pragma solidity ^0.8.5;
pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/math/SafeCast.sol";
import "./RewardSource.sol";
import "./ScaleCodec.sol";
import "./OutboundChannel.sol";
Expand All @@ -13,19 +14,20 @@ enum ChannelId {
}

contract ETHApp is RewardSource, AccessControl {
using ScaleCodec for uint256;
using ScaleCodec for uint128;
using ScaleCodec for uint32;
using SafeCast for uint256;

mapping(ChannelId => Channel) public channels;

event Locked(
address sender,
bytes32 recipient,
uint256 amount,
uint128 amount,
uint32 paraId
);

event Unlocked(bytes32 sender, address recipient, uint256 amount);
event Unlocked(bytes32 sender, address recipient, uint128 amount);

event Upgraded(
address upgrader,
Expand Down Expand Up @@ -82,22 +84,16 @@ contract ETHApp is RewardSource, AccessControl {
"Invalid channel ID"
);

emit Locked(msg.sender, _recipient, msg.value, _paraId);
// evert in case of overflow.
uint128 value = (msg.value).toUint128();

emit Locked(msg.sender, _recipient, value, _paraId);

bytes memory call;
if(_paraId == 0) {
call = encodeCall(
msg.sender,
_recipient,
msg.value
);
if (_paraId == 0) {
call = encodeCall(msg.sender, _recipient, value);
} else {
call = encodeCallWithParaId(
msg.sender,
_recipient,
msg.value,
_paraId
);
call = encodeCallWithParaId(msg.sender, _recipient, value, _paraId);
}

OutboundChannel channel = OutboundChannel(
Expand All @@ -109,7 +105,7 @@ contract ETHApp is RewardSource, AccessControl {
function unlock(
bytes32 _sender,
address payable _recipient,
uint256 _amount
uint128 _amount
) public onlyRole(INBOUND_CHANNEL_ROLE) {
require(_amount > 0, "Must unlock a positive amount");

Expand All @@ -122,14 +118,15 @@ contract ETHApp is RewardSource, AccessControl {
function encodeCall(
address _sender,
bytes32 _recipient,
uint256 _amount
uint128 _amount
) private pure returns (bytes memory) {
return abi.encodePacked(
return
abi.encodePacked(
MINT_CALL,
_sender,
bytes1(0x00), // Encode recipient as MultiAddress::Id
_recipient,
_amount.encode256(),
_amount.encode128(),
bytes1(0x00)
);
}
Expand All @@ -138,21 +135,22 @@ contract ETHApp is RewardSource, AccessControl {
function encodeCallWithParaId(
address _sender,
bytes32 _recipient,
uint256 _amount,
uint128 _amount,
uint32 _paraId
) private pure returns (bytes memory) {
return abi.encodePacked(
return
abi.encodePacked(
MINT_CALL,
_sender,
bytes1(0x00), // Encode recipient as MultiAddress::Id
_recipient,
_amount.encode256(),
_amount.encode128(),
bytes1(0x01),
_paraId.encode32()
);
}

function reward(address payable _recipient, uint256 _amount)
function reward(address payable _recipient, uint128 _amount)
external
override
onlyRole(REWARD_ROLE)
Expand Down
4 changes: 2 additions & 2 deletions ethereum/contracts/IncentivizedInboundChannel.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ contract IncentivizedInboundChannel is AccessControl {
struct Message {
address target;
uint64 nonce;
uint256 fee;
uint128 fee;
bytes payload;
}

Expand Down Expand Up @@ -81,7 +81,7 @@ contract IncentivizedInboundChannel is AccessControl {
address payable _relayer,
Message[] calldata _messages
) internal {
uint256 _rewardAmount = 0;
uint128 _rewardAmount = 0;
// Caching nonce for gas optimization
uint64 cachedNonce = nonce;

Expand Down
2 changes: 1 addition & 1 deletion ethereum/contracts/RewardSource.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ pragma experimental ABIEncoderV2;

// Something that can reward a relayer
interface RewardSource {
function reward(address payable feePayer, uint256 _amount) external;
function reward(address payable feePayer, uint128 _amount) external;
}
4 changes: 3 additions & 1 deletion ethereum/contracts/test/MockOutboundChannel.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ pragma experimental ABIEncoderV2;
import "../OutboundChannel.sol";

contract MockOutboundChannel is OutboundChannel {
function submit(address, bytes calldata) external override {
event Message(address source, bytes data);

function submit(address, bytes calldata data) external override {
emit Message(msg.sender, data);
}
}
2 changes: 1 addition & 1 deletion ethereum/contracts/test/MockRewardSource.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ pragma experimental ABIEncoderV2;
import "../RewardSource.sol";

contract MockRewardSource is RewardSource {
function reward(address payable, uint256 _amount) pure external override {
function reward(address payable, uint128 _amount) pure external override {
// Simulate the case where there are no funds to reward the relayer
require(_amount != 1024, "No funds available");
}
Expand Down
Loading

0 comments on commit f27b762

Please sign in to comment.