Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
19 changed files
with
1,461 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
pragma solidity 0.4.24; | ||
|
||
interface IMintHandler { | ||
function mint(address _to, uint256 _amount) external returns (bool); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "../interfaces/IMintHandler.sol"; | ||
import "../interfaces/IBurnableMintableERC677Token.sol"; | ||
import "openzeppelin-solidity/contracts/ownership/Ownable.sol"; | ||
|
||
contract MintHandlerMock is IMintHandler, Ownable { | ||
IBurnableMintableERC677Token public token; | ||
|
||
mapping(address => bool) public isBridge; | ||
|
||
constructor(address _token) public { | ||
token = IBurnableMintableERC677Token(_token); | ||
} | ||
|
||
function addBridge(address _bridge) external onlyOwner { | ||
isBridge[_bridge] = true; | ||
} | ||
|
||
function removeBridge(address _bridge) external onlyOwner { | ||
delete isBridge[_bridge]; | ||
} | ||
|
||
function mint(address _to, uint256 _amount) external returns (bool) { | ||
require(isBridge[msg.sender]); | ||
return token.mint(_to, _amount); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 13 additions & 0 deletions
13
contracts/upgradeable_contracts/amb_erc677_to_erc677/BasicStakeTokenMediator.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "./BasicAMBErc677ToErc677.sol"; | ||
|
||
contract BasicStakeTokenMediator is BasicAMBErc677ToErc677 { | ||
function getBridgeInterfacesVersion() external pure returns (uint64 major, uint64 minor, uint64 patch) { | ||
return (1, 0, 0); | ||
} | ||
|
||
function getBridgeMode() external pure returns (bytes4 _data) { | ||
return 0x16ea01e9; // bytes4(keccak256(abi.encodePacked("stake-erc-to-erc-amb"))) | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
contracts/upgradeable_contracts/amb_erc677_to_erc677/ForeignStakeTokenMediator.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "./BasicStakeTokenMediator.sol"; | ||
import "../../interfaces/IBurnableMintableERC677Token.sol"; | ||
|
||
contract ForeignStakeTokenMediator is BasicStakeTokenMediator { | ||
/** | ||
* @dev Executes action on the request to withdraw tokens relayed from the other network | ||
* @param _recipient address of tokens receiver | ||
* @param _value amount of bridged tokens | ||
*/ | ||
function executeActionOnBridgedTokens(address _recipient, uint256 _value) internal { | ||
uint256 value = _value.div(10**decimalShift()); | ||
_transferWithOptionalMint(_recipient, value); | ||
} | ||
|
||
/** | ||
* @dev Executes action on deposit of bridged tokens | ||
* @param _from address of tokens sender | ||
* @param _value requsted amount of bridged tokens | ||
* @param _data alternative receiver, if specified | ||
*/ | ||
function bridgeSpecificActionsOnTokenTransfer( | ||
ERC677, /* _token */ | ||
address _from, | ||
uint256 _value, | ||
bytes _data | ||
) internal { | ||
if (!lock()) { | ||
passMessage(chooseReceiver(_from, _data), _value); | ||
} | ||
} | ||
|
||
/** | ||
* @dev Executes action on relayed request to fix the failed transfer of tokens | ||
* @param _recipient address of tokens receiver | ||
* @param _value amount of fixed tokens | ||
*/ | ||
function executeActionOnFixedTokens(address _recipient, uint256 _value) internal { | ||
_transferWithOptionalMint(_recipient, _value); | ||
} | ||
|
||
/** | ||
* @dev Internal function for transfer of tokens, with optional minting if current balance is insufficient | ||
* @param _recipient address of tokens receiver | ||
* @param _value amount of fixed tokens | ||
*/ | ||
function _transferWithOptionalMint(address _recipient, uint256 _value) internal { | ||
IBurnableMintableERC677Token token = IBurnableMintableERC677Token(erc677token()); | ||
uint256 balance = token.balanceOf(address(this)); | ||
if (_recipient != address(0) && balance == 0) { | ||
token.mint(_recipient, _value); | ||
} else if (balance < _value) { | ||
token.mint(address(this), _value - balance); | ||
token.transfer(_recipient, _value); | ||
} else { | ||
token.transfer(_recipient, _value); | ||
} | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
contracts/upgradeable_contracts/amb_erc677_to_erc677/HomeStakeTokenFeeManager.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "../BlockRewardBridge.sol"; | ||
import "../Ownable.sol"; | ||
import "openzeppelin-solidity/contracts/math/SafeMath.sol"; | ||
|
||
contract HomeStakeTokenFeeManager is BlockRewardBridge, Ownable { | ||
using SafeMath for uint256; | ||
|
||
event FeeUpdated(uint256 fee); | ||
|
||
uint256 internal constant MAX_FEE = 1 ether; | ||
bytes32 internal constant FEE = 0x241773621b963145d8e249ca69b0240df7de56fca52fb3ec9e2ddd08a968570e; // keccak256(abi.encodePacked("stakeTokenFee")); | ||
|
||
/** | ||
* @dev Retrieves currently used block reward contract | ||
* @return configured block reward contract address | ||
*/ | ||
function blockRewardContract() external view returns (IBlockReward) { | ||
return _blockRewardContract(); | ||
} | ||
|
||
/** | ||
* @dev Updates address of currently used block reward contract | ||
* @param _blockReward address of a new contract | ||
*/ | ||
function setBlockRewardContract(address _blockReward) external onlyOwner { | ||
_setBlockRewardContract(_blockReward); | ||
} | ||
|
||
/** | ||
* @dev Retrieves current fee value | ||
* @return current value of fee, 1e18 is 100% | ||
*/ | ||
function getFee() public view returns (uint256) { | ||
return uintStorage[FEE]; | ||
} | ||
|
||
/** | ||
* @dev Calculates the fee amount to be subtracted from the value. | ||
* @param _value the base value from which fees are calculated | ||
*/ | ||
function calculateFee(uint256 _value) public view returns (uint256) { | ||
return _value.mul(getFee()).div(MAX_FEE); | ||
} | ||
|
||
/** | ||
* @dev Sets the fee percentage amount for the mediator operations. Only the owner can call this method. | ||
* @param _fee the fee percentage | ||
*/ | ||
function setFee(uint256 _fee) external onlyOwner { | ||
_setFee(_fee); | ||
} | ||
|
||
/** | ||
* @dev Internal setter for fee | ||
* @param _fee the fee percentage | ||
*/ | ||
function _setFee(uint256 _fee) internal { | ||
require(_fee < MAX_FEE); | ||
uintStorage[FEE] = _fee; | ||
emit FeeUpdated(_fee); | ||
} | ||
} |
160 changes: 160 additions & 0 deletions
160
contracts/upgradeable_contracts/amb_erc677_to_erc677/HomeStakeTokenMediator.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
pragma solidity 0.4.24; | ||
|
||
import "../../interfaces/IMintHandler.sol"; | ||
import "./BasicStakeTokenMediator.sol"; | ||
import "../BlockRewardBridge.sol"; | ||
import "./HomeStakeTokenFeeManager.sol"; | ||
import "../../interfaces/IBurnableMintableERC677Token.sol"; | ||
|
||
contract HomeStakeTokenMediator is BasicStakeTokenMediator, HomeStakeTokenFeeManager { | ||
bytes32 internal constant MINT_HANDLER = 0x8a8236f871f2bbb44f59e8c68b82f7587d19c987e09aba39148cc97ea004a32e; // keccak256(abi.encodePacked("mintHandler")) | ||
|
||
/** | ||
* Initializes home mediator | ||
* @param _bridgeContract HomeAMB bridge contract | ||
* @param _mediatorContract address of the mediator contract in the Foreign chain | ||
* @param _erc677token address of STAKE token in the Home chain | ||
* @param _dailyLimitMaxPerTxMinPerTxArray Home limits for outgoing transfers | ||
* @param _executionDailyLimitExecutionMaxPerTxArray Home execution limits for incoming transfers | ||
* @param _requestGasLimit gas limit used for AMB operations | ||
* @param _decimalShift decimal shift for bridged TAKE token | ||
* @param _owner address of new bridge owner | ||
*/ | ||
function initialize( | ||
address _bridgeContract, | ||
address _mediatorContract, | ||
address _erc677token, | ||
uint256[] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = _dailyLimit, 1 = _maxPerTx, 2 = _minPerTx ] | ||
uint256[] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = _executionDailyLimit, 1 = _executionMaxPerTx ] | ||
uint256 _requestGasLimit, | ||
uint256 _decimalShift, | ||
address _owner | ||
) public returns (bool) { | ||
addressStorage[MINT_HANDLER] = _erc677token; | ||
return | ||
super.initialize( | ||
_bridgeContract, | ||
_mediatorContract, | ||
_erc677token, | ||
_dailyLimitMaxPerTxMinPerTxArray, | ||
_executionDailyLimitExecutionMaxPerTxArray, | ||
_requestGasLimit, | ||
_decimalShift, | ||
_owner | ||
); | ||
} | ||
|
||
/** | ||
* Initializes rewardable home mediator | ||
* @param _bridgeContract HomeAMB bridge contract | ||
* @param _mediatorContract address of the mediator contract in the Foreign chain | ||
* @param _erc677token address of STAKE token in the Home chain | ||
* @param _dailyLimitMaxPerTxMinPerTxArray Home limits for outgoing transfers | ||
* @param _executionDailyLimitExecutionMaxPerTxArray Home execution limits for incoming transfers | ||
* @param _requestGasLimit gas limit used for AMB operations | ||
* @param _decimalShift decimal shift for bridged TAKE token | ||
* @param _owner address of new bridge owner | ||
* @param _blockReward address of block reward contract used for fee distribution | ||
* @param _fee initial home fee | ||
*/ | ||
function rewardableInitialize( | ||
address _bridgeContract, | ||
address _mediatorContract, | ||
address _erc677token, | ||
uint256[] _dailyLimitMaxPerTxMinPerTxArray, // [ 0 = _dailyLimit, 1 = _maxPerTx, 2 = _minPerTx ] | ||
uint256[] _executionDailyLimitExecutionMaxPerTxArray, // [ 0 = _executionDailyLimit, 1 = _executionMaxPerTx ] | ||
uint256 _requestGasLimit, | ||
uint256 _decimalShift, | ||
address _owner, | ||
address _blockReward, | ||
uint256 _fee | ||
) external returns (bool) { | ||
_setFee(_fee); | ||
_setBlockRewardContract(_blockReward); | ||
return | ||
initialize( | ||
_bridgeContract, | ||
_mediatorContract, | ||
_erc677token, | ||
_dailyLimitMaxPerTxMinPerTxArray, | ||
_executionDailyLimitExecutionMaxPerTxArray, | ||
_requestGasLimit, | ||
_decimalShift, | ||
_owner | ||
); | ||
} | ||
|
||
/** | ||
* @dev Allows to transfer token ownership to different proxy contract. | ||
* Can be called only once, when mediator is the current owner of a token. | ||
* All subsequent calls to erc677 token will be done through new proxy contract. | ||
* @param _owner token proxy contract address | ||
*/ | ||
function transferTokenOwnership(address _owner) external onlyOwner { | ||
Ownable(erc677token()).transferOwnership(_owner); | ||
} | ||
|
||
/** | ||
* @dev Updates address of contract used for handling mint operations, | ||
* all subsequent mint operations will be called through this contract | ||
* @param _mintHandler address of new contract | ||
*/ | ||
function setMintHandler(address _mintHandler) external onlyOwner { | ||
require(AddressUtils.isContract(_mintHandler)); | ||
addressStorage[MINT_HANDLER] = _mintHandler; | ||
} | ||
|
||
/** | ||
* @dev Retrieves currently used contract for handling mint operations, defaults to token itself | ||
* @return address of mint handler contract | ||
*/ | ||
function getMintHandler() public view returns (IMintHandler) { | ||
return IMintHandler(addressStorage[MINT_HANDLER]); | ||
} | ||
|
||
/** | ||
* @dev Executes action on the request to deposit tokens relayed from the other network | ||
* @param _recipient address of tokens receiver | ||
* @param _value amount of bridged tokens | ||
*/ | ||
function executeActionOnBridgedTokens(address _recipient, uint256 _value) internal { | ||
uint256 value = _value.mul(10**decimalShift()); | ||
getMintHandler().mint(_recipient, value); | ||
} | ||
|
||
/** | ||
* @dev Executes action on withdrawal of bridged tokens | ||
* @param _token address of token contract | ||
* @param _from address of tokens sender | ||
* @param _value requsted amount of bridged tokens | ||
* @param _data alternative receiver, if specified | ||
*/ | ||
function bridgeSpecificActionsOnTokenTransfer(ERC677 _token, address _from, uint256 _value, bytes _data) internal { | ||
if (!lock()) { | ||
// burn all incoming tokens | ||
IBurnableMintableERC677Token(_token).burn(_value); | ||
|
||
if (address(_blockRewardContract()) == address(0)) { | ||
// in case if block reward contract is not configured, the fee is not collected | ||
passMessage(chooseReceiver(_from, _data), _value); | ||
} else { | ||
// when block reward contract is defined, the calculated fee is subtracted from the original value | ||
uint256 fee = calculateFee(_value); | ||
passMessage(chooseReceiver(_from, _data), _value.sub(fee)); | ||
if (fee > 0) { | ||
// the fee itself is distributed later in the block reward contract | ||
_blockRewardContract().addBridgeTokenRewardReceivers(fee); | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @dev Executes action on relayed request to fix the failed transfer of tokens | ||
* @param _recipient address of tokens receiver | ||
* @param _value amount of fixed tokens | ||
*/ | ||
function executeActionOnFixedTokens(address _recipient, uint256 _value) internal { | ||
getMintHandler().mint(_recipient, _value); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.