Skip to content

Commit

Permalink
Restrict relay of tokens for other user (#475)
Browse files Browse the repository at this point in the history
  • Loading branch information
k1rill-fedoseev authored Aug 22, 2020
1 parent 8748332 commit df296d1
Show file tree
Hide file tree
Showing 21 changed files with 177 additions and 1,031 deletions.
13 changes: 2 additions & 11 deletions contracts/upgradeable_contracts/ERC20Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,14 @@ contract ERC20Bridge is BasicForeignBridge {
addressStorage[ERC20_TOKEN] = _token;
}

function _relayTokens(address _sender, address _receiver, uint256 _amount) internal {
function relayTokens(address _receiver, uint256 _amount) external {
require(_receiver != address(0));
require(_receiver != address(this));
require(_amount > 0);
require(withinLimit(_amount));
addTotalSpentPerDay(getCurrentDay(), _amount);

erc20token().transferFrom(_sender, address(this), _amount);
erc20token().transferFrom(msg.sender, address(this), _amount);
emit UserRequestForAffirmation(_receiver, _amount);
}

function relayTokens(address _from, address _receiver, uint256 _amount) external {
require(_from == msg.sender || _from == _receiver);
_relayTokens(_from, _receiver, _amount);
}

function relayTokens(address _receiver, uint256 _amount) external {
_relayTokens(msg.sender, _receiver, _amount);
}
}
2 changes: 1 addition & 1 deletion contracts/upgradeable_contracts/VersionableBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ pragma solidity 0.4.24;

contract VersionableBridge {
function getBridgeInterfacesVersion() external pure returns (uint64 major, uint64 minor, uint64 patch) {
return (5, 0, 0);
return (5, 1, 0);
}

/* solcov ignore next */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ contract BasicAMBErc20ToNative is Initializable, Upgradeable, Claimable, Version
* @return patch value of the version
*/
function getBridgeInterfacesVersion() external pure returns (uint64 major, uint64 minor, uint64 patch) {
return (1, 0, 0);
return (1, 1, 0);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,26 +58,27 @@ contract ForeignAMBErc20ToNative is BasicAMBErc20ToNative, ReentrancyGuard, Base
return _erc677token();
}

/**
* @dev It will initiate the bridge operation that will lock the amount of tokens transferred and mint the native tokens on
* the other network. The user should first call Approve method of the ERC677 token.
* @param _from address that will transfer the tokens to be locked.
* @param _receiver address that will receive the native tokens on the other network.
* @param _value amount of tokens to be transferred to the other network.
*/
function relayTokens(address _from, address _receiver, uint256 _value) external {
require(_from == msg.sender || _from == _receiver);
_relayTokens(_from, _receiver, _value);
}

/**
* @dev It will initiate the bridge operation that will lock the amount of tokens transferred and mint the native tokens on
* the other network. The user should first call Approve method of the ERC677 token.
* @param _receiver address that will receive the native tokens on the other network.
* @param _value amount of tokens to be transferred to the other network.
*/
function relayTokens(address _receiver, uint256 _value) external {
_relayTokens(msg.sender, _receiver, _value);
// This lock is to prevent calling passMessage twice.
// When transferFrom is called, after the transfer, the ERC677 token will call onTokenTransfer from this contract
// which will call passMessage.
require(!lock());
ERC677 token = _erc677token();
address to = address(this);
require(withinLimit(_value));
addTotalSpentPerDay(getCurrentDay(), _value);
_setMediatorBalance(mediatorBalance().add(_value));

setLock(true);
token.transferFrom(msg.sender, to, _value);
setLock(false);
bridgeSpecificActionsOnTokenTransfer(token, msg.sender, _value, abi.encodePacked(_receiver));
}

/**
Expand Down Expand Up @@ -181,31 +182,6 @@ contract ForeignAMBErc20ToNative is BasicAMBErc20ToNative, ReentrancyGuard, Base
}
}

/**
* @dev Validates that the token amount is inside the limits, calls transferFrom to transfer the tokens to the contract
* and invokes the method to lock the tokens and mint the native tokens on the other network.
* The user should first call Approve method of the ERC677 token.
* @param _from address that will transfer the tokens to be locked.
* @param _receiver address that will receive the native tokens on the other network.
* @param _value amount of tokens to be transferred to the other network.
*/
function _relayTokens(address _from, address _receiver, uint256 _value) internal {
// This lock is to prevent calling passMessage twice.
// When transferFrom is called, after the transfer, the ERC677 token will call onTokenTransfer from this contract
// which will call passMessage.
require(!lock());
ERC677 token = _erc677token();
address to = address(this);
require(withinLimit(_value));
addTotalSpentPerDay(getCurrentDay(), _value);
_setMediatorBalance(mediatorBalance().add(_value));

setLock(true);
token.transferFrom(_from, to, _value);
setLock(false);
bridgeSpecificActionsOnTokenTransfer(token, _from, _value, abi.encodePacked(_receiver));
}

/**
* @dev Tells the address of the mediator contract on the other side, used by chooseReceiver method
* to avoid sending the native tokens to that address.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,7 @@ contract BasicAMBErc677ToErc677 is
return mediatorContractOnOtherSide();
}

function relayTokens(address _from, address _receiver, uint256 _value) external {
require(_from == msg.sender || _from == _receiver);
_relayTokens(_from, _receiver, _value);
}

function _relayTokens(address _from, address _receiver, uint256 _value) internal {
function relayTokens(address _receiver, uint256 _value) external {
// This lock is to prevent calling passMessage twice if a ERC677 token is used.
// When transferFrom is called, after the transfer, the ERC677 token will call onTokenTransfer from this contract
// which will call passMessage.
Expand All @@ -78,13 +73,9 @@ contract BasicAMBErc677ToErc677 is
addTotalSpentPerDay(getCurrentDay(), _value);

setLock(true);
token.transferFrom(_from, to, _value);
token.transferFrom(msg.sender, to, _value);
setLock(false);
bridgeSpecificActionsOnTokenTransfer(token, _from, _value, abi.encodePacked(_receiver));
}

function relayTokens(address _receiver, uint256 _value) external {
_relayTokens(msg.sender, _receiver, _value);
bridgeSpecificActionsOnTokenTransfer(token, msg.sender, _value, abi.encodePacked(_receiver));
}

function onTokenTransfer(address _from, uint256 _value, bytes _data) external returns (bool) {
Expand All @@ -99,7 +90,7 @@ contract BasicAMBErc677ToErc677 is
}

function getBridgeInterfacesVersion() external pure returns (uint64 major, uint64 minor, uint64 patch) {
return (1, 1, 0);
return (1, 2, 0);
}

function getBridgeMode() external pure returns (bytes4 _data) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import "./BasicAMBErc677ToErc677.sol";

contract BasicStakeTokenMediator is BasicAMBErc677ToErc677 {
function getBridgeInterfacesVersion() external pure returns (uint64 major, uint64 minor, uint64 patch) {
return (1, 0, 0);
return (1, 1, 0);
}

function getBridgeMode() external pure returns (bytes4 _data) {
Expand Down
66 changes: 32 additions & 34 deletions contracts/upgradeable_contracts/amb_erc677_to_erc677/callflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -321,25 +321,24 @@ This will allow to the mediator contract to call the `transferFrom` method from
```=
>>Mediator
BasicAMBErc677ToErc677::relayTokens
..BasicAMBErc677ToErc677::_relayTokens
>>Token
....ERC677BridgeToken::transferFrom
......ERC677BridgeToken::_superTransferFrom
........ERC20Permittable::transferFrom
..........ERC20::_transfer
............emit Transfer
......ERC677BridgeToken::_callAfterTransfer
........ERC677BridgeToken::_contractFallback
..ERC677BridgeToken::transferFrom
....ERC677BridgeToken::_superTransferFrom
......ERC20Permittable::transferFrom
........ERC20::_transfer
..........emit Transfer
....ERC677BridgeToken::_callAfterTransfer
......ERC677BridgeToken::_contractFallback
>>Mediator
..........BasicAMBErc677ToErc677::onTokenTransfer
............ForeignStakeTokenMediator::bridgeSpecificActionsOnTokenTransfer
..............TokenBridgeMediator::passMessage
................TokenBridgeMediator::setMessageHashValue
................TokenBridgeMediator::setMessageHashRecipient
........BasicAMBErc677ToErc677::onTokenTransfer
..........ForeignStakeTokenMediator::bridgeSpecificActionsOnTokenTransfer
............TokenBridgeMediator::passMessage
..............TokenBridgeMediator::setMessageHashValue
..............TokenBridgeMediator::setMessageHashRecipient
>>Bridge
................MessageDelivery::requireToPassMessage
..................ForeignAMB::emitEventOnMessageRequest
....................emit UserRequestForAffirmation
..............MessageDelivery::requireToPassMessage
................ForeignAMB::emitEventOnMessageRequest
..................emit UserRequestForAffirmation
```

#### Execution
Expand All @@ -355,30 +354,29 @@ The mediator on the Home side also provides the `relayTokens` method. Prior to i
```=
>>Mediator
BasicAMBErc677ToErc677::relayTokens
..BasicAMBErc677ToErc677::_relayTokens
>>Token
....ERC677BridgeTokenRewardable::transferFrom
......PermittableToken::transferFrom
........emit Transfer
........ERC677BridgeToken::callAfterTransfer
..........ERC677BridgeToken::contractFallback
..ERC677BridgeTokenRewardable::transferFrom
....PermittableToken::transferFrom
......emit Transfer
......ERC677BridgeToken::callAfterTransfer
........ERC677BridgeToken::contractFallback
>>Mediator
............BasicAMBErc677ToErc677::onTokenTransfer
..............HomeStakeTokenMediator::bridgeSpecificActionsOnTokenTransfer
..........BasicAMBErc677ToErc677::onTokenTransfer
............HomeStakeTokenMediator::bridgeSpecificActionsOnTokenTransfer
>>Token
................BurnableToken::burn
..................BurnableToken::_burn
..............BurnableToken::burn
................BurnableToken::_burn
>>Mediator
................TokenBridgeMediator::passMessage
..................TokenBridgeMediator::setMessageHashValue
..................TokenBridgeMediator::setMessageHashRecipient
..............TokenBridgeMediator::passMessage
................TokenBridgeMediator::setMessageHashValue
................TokenBridgeMediator::setMessageHashRecipient
>>Bridge
..................MessageDelivery::requireToPassMessage
....................ForeignAMB::emitEventOnMessageRequest
......................emit UserRequestForSignature
................MessageDelivery::requireToPassMessage
..................ForeignAMB::emitEventOnMessageRequest
....................emit UserRequestForSignature
>>BlockReward
................HomeStakeTokenFeeManager::_distributeFee
..................BlockRewardAuRaTokens::addBridgeTokenRewardReceivers
..............HomeStakeTokenFeeManager::_distributeFee
................BlockRewardAuRaTokens::addBridgeTokenRewardReceivers
```

#### Execution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,24 +94,10 @@ contract ForeignAMBNativeToErc20 is BasicAMBNativeToErc20, ReentrancyGuard, Base
/**
* @dev It will initiate the bridge operation that will burn the amount of tokens transferred and unlock the native tokens on
* the other network. The user should first call Approve method of the ERC677 token.
* @param _from address that will transfer the tokens to be burned.
* @param _receiver address that will receive the native tokens on the other network.
* @param _value amount of tokens to be transferred to the other network.
*/
function relayTokens(address _from, address _receiver, uint256 _value) external {
require(_from == msg.sender || _from == _receiver);
_relayTokens(_from, _receiver, _value);
}

/**
* @dev Validates that the token amount is inside the limits, calls transferFrom to transfer the tokens to the contract
* and invokes the method to burn the tokens and unlock the native tokens on the other network.
* The user should first call Approve method of the ERC677 token.
* @param _from address that will transfer the tokens to be burned.
* @param _receiver address that will receive the native tokens on the other network.
* @param _value amount of tokens to be transferred to the other network.
*/
function _relayTokens(address _from, address _receiver, uint256 _value) internal {
function relayTokens(address _receiver, uint256 _value) external {
// This lock is to prevent calling passMessage twice.
// When transferFrom is called, after the transfer, the ERC677 token will call onTokenTransfer from this contract
// which will call passMessage.
Expand All @@ -122,19 +108,9 @@ contract ForeignAMBNativeToErc20 is BasicAMBNativeToErc20, ReentrancyGuard, Base
addTotalSpentPerDay(getCurrentDay(), _value);

setLock(true);
token.transferFrom(_from, to, _value);
token.transferFrom(msg.sender, to, _value);
setLock(false);
bridgeSpecificActionsOnTokenTransfer(token, _from, _value, abi.encodePacked(_receiver));
}

/**
* @dev It will initiate the bridge operation that will burn the amount of tokens transferred and unlock the native tokens on
* the other network. The user should first call Approve method of the ERC677 token.
* @param _receiver address that will receive the native tokens on the other network.
* @param _value amount of tokens to be transferred to the other network.
*/
function relayTokens(address _receiver, uint256 _value) external {
_relayTokens(msg.sender, _receiver, _value);
bridgeSpecificActionsOnTokenTransfer(token, msg.sender, _value, abi.encodePacked(_receiver));
}

/**
Expand Down
31 changes: 15 additions & 16 deletions contracts/upgradeable_contracts/amb_native_to_erc20/callflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,27 +334,26 @@ This will allow to the mediator contract to call the `transferFrom` method from
```=
>>Mediator
ForeignAMBNativeToErc20::relayTokens
..ForeignAMBNativeToErc20::_relayTokens
>>Token
....ERC677BridgeToken::transferFrom
......StandardToken::transferFrom
........emit Transfer
......ERC677BridgeToken::callAfterTransfer
........ERC677BridgeToken::contractFallback
..ERC677BridgeToken::transferFrom
....StandardToken::transferFrom
......emit Transfer
....ERC677BridgeToken::callAfterTransfer
......ERC677BridgeToken::contractFallback
>>Mediator
..........ForeignAMBNativeToErc20::onTokenTransfer
............ForeignAMBNativeToErc20::bridgeSpecificActionsOnTokenTransfer
........ForeignAMBNativeToErc20::onTokenTransfer
..........ForeignAMBNativeToErc20::bridgeSpecificActionsOnTokenTransfer
>>Token
..............BurnableToken::burn
................BurnableToken::_burn
............BurnableToken::burn
..............BurnableToken::_burn
>>Mediator
..............TokenBridgeMediator::passMessage
................TokenBridgeMediator::setMessageHashValue
................TokenBridgeMediator::setMessageHashRecipient
............TokenBridgeMediator::passMessage
..............TokenBridgeMediator::setMessageHashValue
..............TokenBridgeMediator::setMessageHashRecipient
>>Bridge
................MessageDelivery::requireToPassMessage
..................ForeignAMB::emitEventOnMessageRequest
....................emit UserRequestForAffirmation
..............MessageDelivery::requireToPassMessage
................ForeignAMB::emitEventOnMessageRequest
..................emit UserRequestForAffirmation
```

#### Execution
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,41 +80,15 @@ contract ForeignBridgeErcToNative is BasicForeignBridge, ERC20Bridge, OtherSideB
}

function relayTokens(address _receiver, uint256 _amount) external {
_relayTokens(msg.sender, _receiver, _amount, erc20token());
}

function relayTokens(address _sender, address _receiver, uint256 _amount) external {
relayTokens(_sender, _receiver, _amount, erc20token());
}

function relayTokens(address _from, address _receiver, uint256 _amount, address _token) public {
require(_from == msg.sender || _from == _receiver);
_relayTokens(_from, _receiver, _amount, _token);
}

function relayTokens(address _receiver, uint256 _amount, address _token) external {
_relayTokens(msg.sender, _receiver, _amount, _token);
}

function _relayTokens(address _sender, address _receiver, uint256 _amount, address _token) internal {
require(_receiver != bridgeContractOnOtherSide());
require(_receiver != address(0));
require(_receiver != address(this));
require(_amount > 0);
require(withinLimit(_amount));

ERC20 tokenToOperate = ERC20(_token);
ERC20 fdToken = erc20token();

if (tokenToOperate == ERC20(0x0)) {
tokenToOperate = fdToken;
}

require(tokenToOperate == fdToken);

addTotalSpentPerDay(getCurrentDay(), _amount);

tokenToOperate.transferFrom(_sender, address(this), _amount);
erc20token().transferFrom(msg.sender, address(this), _amount);
emit UserRequestForAffirmation(_receiver, _amount);

if (isDaiNeedsToBeInvested()) {
Expand Down
Loading

0 comments on commit df296d1

Please sign in to comment.