Skip to content

Commit

Permalink
Merge pull request #109 from poanetwork/extend-limits-functionality-1…
Browse files Browse the repository at this point in the history
….1-rc0

Extend Native-ERC20 limits functionality on contracts v1.1
  • Loading branch information
akolotov authored Dec 11, 2018
2 parents aaad596 + 17f6112 commit 9623988
Show file tree
Hide file tree
Showing 7 changed files with 229 additions and 52 deletions.
41 changes: 40 additions & 1 deletion contracts/upgradeable_contracts/U_ForeignBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ contract ForeignBridge is ERC677Receiver, BasicBridge {
event SignedForDeposit(address indexed signer, bytes32 transactionHash);
event SignedForWithdraw(address indexed signer, bytes32 messageHash);
event DailyLimit(uint256 newLimit);
event HomeDailyLimit(uint256 newLimit);

function initialize(
address _validatorContract,
Expand All @@ -31,11 +32,14 @@ contract ForeignBridge is ERC677Receiver, BasicBridge {
uint256 _maxPerTx,
uint256 _minPerTx,
uint256 _foreignGasPrice,
uint256 _requiredBlockConfirmations
uint256 _requiredBlockConfirmations,
uint256 _homeDailyLimit,
uint256 _homeMaxPerTx
) public returns(bool) {
require(!isInitialized());
require(_validatorContract != address(0));
require(_minPerTx > 0 && _maxPerTx > _minPerTx && _foreignDailyLimit > _maxPerTx);
require(_homeMaxPerTx < _homeDailyLimit);
require(_foreignGasPrice > 0);
addressStorage[keccak256("validatorContract")] = _validatorContract;
setErc677token(_erc677token);
Expand All @@ -45,6 +49,8 @@ contract ForeignBridge is ERC677Receiver, BasicBridge {
uintStorage[keccak256("minPerTx")] = _minPerTx;
uintStorage[keccak256("gasPrice")] = _foreignGasPrice;
uintStorage[keccak256("requiredBlockConfirmations")] = _requiredBlockConfirmations;
uintStorage[keccak256("homeDailyLimit")] = _homeDailyLimit;
uintStorage[keccak256("homeMaxPerTx")] = _homeMaxPerTx;
setInitialize(true);
return isInitialized();
}
Expand All @@ -63,6 +69,11 @@ contract ForeignBridge is ERC677Receiver, BasicBridge {
uintStorage[keccak256("maxPerTx")] = _maxPerTx;
}

function setHomeMaxPerTx(uint256 _maxPerTx) external onlyOwner {
require(_maxPerTx < homeDailyLimit());
uintStorage[keccak256("homeMaxPerTx")] = _maxPerTx;
}

function setMinPerTx(uint256 _minPerTx) external onlyOwner {
require(_minPerTx < foreignDailyLimit() && _minPerTx < maxPerTx());
uintStorage[keccak256("minPerTx")] = _minPerTx;
Expand Down Expand Up @@ -92,10 +103,18 @@ contract ForeignBridge is ERC677Receiver, BasicBridge {
return uintStorage[keccak256("maxPerTx")];
}

function homeMaxPerTx() public view returns(uint256) {
return uintStorage[keccak256("homeMaxPerTx")];
}

function totalSpentPerDay(uint256 _day) public view returns(uint256) {
return uintStorage[keccak256("totalSpentPerDay", _day)];
}

function totalExecutedPerDay(uint256 _day) public view returns(uint256) {
return uintStorage[keccak256("totalExecutedPerDay", _day)];
}

function deployedAtBlock() public view returns(uint256) {
return uintStorage[keccak256("deployedAtBlock")];
}
Expand All @@ -112,6 +131,10 @@ contract ForeignBridge is ERC677Receiver, BasicBridge {
return uintStorage[keccak256("foreignDailyLimit")];
}

function homeDailyLimit() public view returns(uint256) {
return uintStorage[keccak256("homeDailyLimit")];
}

function erc677token() public view returns(IBurnableMintableERC677Token) {
return IBurnableMintableERC677Token(addressStorage[keccak256("erc677token")]);
}
Expand All @@ -125,6 +148,7 @@ contract ForeignBridge is ERC677Receiver, BasicBridge {
function deposit(address recipient, uint256 value, bytes32 transactionHash) external onlyValidator {
bytes32 hashMsg = keccak256(recipient, value, transactionHash);
bytes32 hashSender = keccak256(msg.sender, hashMsg);
require(withinHomeLimit(value));
// Duplicated deposits
require(!depositsSigned(hashSender));
setDepositsSigned(hashSender, true);
Expand All @@ -141,6 +165,7 @@ contract ForeignBridge is ERC677Receiver, BasicBridge {
if (signed >= validatorContract().requiredSignatures()) {
// If the bridge contract does not own enough tokens to transfer
// it will couse funds lock on the home side of the bridge
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(value));
setNumDepositsSigned(hashMsg, markAsProcessed(signed));
erc677token().mint(recipient, value);
emit Deposit(recipient, value, transactionHash);
Expand Down Expand Up @@ -215,11 +240,21 @@ contract ForeignBridge is ERC677Receiver, BasicBridge {
emit DailyLimit(_foreignDailyLimit);
}

function setHomeDailyLimit(uint256 _homeDailyLimit) external onlyOwner {
uintStorage[keccak256("homeDailyLimit")] = _homeDailyLimit;
emit HomeDailyLimit(_homeDailyLimit);
}

function withinLimit(uint256 _amount) public view returns(bool) {
uint256 nextLimit = totalSpentPerDay(getCurrentDay()).add(_amount);
return foreignDailyLimit() >= nextLimit && _amount <= maxPerTx() && _amount >= minPerTx();
}

function withinHomeLimit(uint256 _amount) public view returns(bool) {
uint256 nextLimit = totalExecutedPerDay(getCurrentDay()).add(_amount);
return homeDailyLimit() >= nextLimit && _amount <= homeMaxPerTx();
}

function isInitialized() public view returns(bool) {
return boolStorage[keccak256("isInitialized")];
}
Expand Down Expand Up @@ -280,6 +315,10 @@ contract ForeignBridge is ERC677Receiver, BasicBridge {
uintStorage[keccak256("totalSpentPerDay", _day)] = _value;
}

function setTotalExecutedPerDay(uint256 _day, uint256 _value) private {
uintStorage[keccak256("totalExecutedPerDay", _day)] = _value;
}

function setErc677token(address _token) private {
require(_token != address(0));
addressStorage[keccak256("erc677token")] = _token;
Expand Down
41 changes: 40 additions & 1 deletion contracts/upgradeable_contracts/U_HomeBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,17 @@ contract HomeBridge is EternalStorage, BasicBridge {
event Deposit (address recipient, uint256 value);
event Withdraw (address recipient, uint256 value, bytes32 transactionHash);
event DailyLimit(uint256 newLimit);
event ForeignDailyLimit(uint256 newLimit);

function initialize (
address _validatorContract,
uint256 _homeDailyLimit,
uint256 _maxPerTx,
uint256 _minPerTx,
uint256 _homeGasPrice,
uint256 _requiredBlockConfirmations
uint256 _requiredBlockConfirmations,
uint256 _foreignDailyLimit,
uint256 _foreignMaxPerTx
) public
returns(bool)
{
Expand All @@ -32,13 +35,16 @@ contract HomeBridge is EternalStorage, BasicBridge {
require(_homeGasPrice > 0);
require(_requiredBlockConfirmations > 0);
require(_minPerTx > 0 && _maxPerTx > _minPerTx && _homeDailyLimit > _maxPerTx);
require(_foreignMaxPerTx < _foreignDailyLimit);
addressStorage[keccak256("validatorContract")] = _validatorContract;
uintStorage[keccak256("deployedAtBlock")] = block.number;
uintStorage[keccak256("homeDailyLimit")] = _homeDailyLimit;
uintStorage[keccak256("maxPerTx")] = _maxPerTx;
uintStorage[keccak256("minPerTx")] = _minPerTx;
uintStorage[keccak256("gasPrice")] = _homeGasPrice;
uintStorage[keccak256("requiredBlockConfirmations")] = _requiredBlockConfirmations;
uintStorage[keccak256("foreignDailyLimit")] = _foreignDailyLimit;
uintStorage[keccak256("foreignMaxPerTx")] = _foreignMaxPerTx;
setInitialize(true);
return isInitialized();
}
Expand All @@ -63,10 +69,18 @@ contract HomeBridge is EternalStorage, BasicBridge {
return uintStorage[keccak256("homeDailyLimit")];
}

function foreignDailyLimit() public view returns(uint256) {
return uintStorage[keccak256("foreignDailyLimit")];
}

function totalSpentPerDay(uint256 _day) public view returns(uint256) {
return uintStorage[keccak256("totalSpentPerDay", _day)];
}

function totalExecutedPerDay(uint256 _day) public view returns(uint256) {
return uintStorage[keccak256("totalExecutedPerDay", _day)];
}

function withdraws(bytes32 _withdraw) public view returns(bool) {
return boolStorage[keccak256("withdraws", _withdraw)];
}
Expand All @@ -82,6 +96,8 @@ contract HomeBridge is EternalStorage, BasicBridge {
uint256 amount;
bytes32 txHash;
(recipient, amount, txHash) = Message.parseMessage(message);
require(withinForeignLimit(amount));
setTotalExecutedPerDay(getCurrentDay(), totalExecutedPerDay(getCurrentDay()).add(amount));
require(!withdraws(txHash));
setWithdraws(txHash, true);

Expand All @@ -103,6 +119,16 @@ contract HomeBridge is EternalStorage, BasicBridge {
uintStorage[keccak256("maxPerTx")] = _maxPerTx;
}

function setForeignDailyLimit(uint256 _foreignDailyLimit) external onlyOwner {
uintStorage[keccak256("foreignDailyLimit")] = _foreignDailyLimit;
emit ForeignDailyLimit(_foreignDailyLimit);
}

function setForeignMaxPerTx(uint256 _maxPerTx) external onlyOwner {
require(_maxPerTx < foreignDailyLimit());
uintStorage[keccak256("foreignMaxPerTx")] = _maxPerTx;
}

function setMinPerTx(uint256 _minPerTx) external onlyOwner {
require(_minPerTx < homeDailyLimit() && _minPerTx < maxPerTx());
uintStorage[keccak256("minPerTx")] = _minPerTx;
Expand All @@ -120,11 +146,20 @@ contract HomeBridge is EternalStorage, BasicBridge {
return uintStorage[keccak256("maxPerTx")];
}

function foreignMaxPerTx() public view returns(uint256) {
return uintStorage[keccak256("foreignMaxPerTx")];
}

function withinLimit(uint256 _amount) public view returns(bool) {
uint256 nextLimit = totalSpentPerDay(getCurrentDay()).add(_amount);
return homeDailyLimit() >= nextLimit && _amount <= maxPerTx() && _amount >= minPerTx();
}

function withinForeignLimit(uint256 _amount) public view returns(bool) {
uint256 nextLimit = totalExecutedPerDay(getCurrentDay()).add(_amount);
return foreignDailyLimit() >= nextLimit && _amount <= foreignMaxPerTx();
}

function isInitialized() public view returns(bool) {
return boolStorage[keccak256("isInitialized")];
}
Expand All @@ -133,6 +168,10 @@ contract HomeBridge is EternalStorage, BasicBridge {
uintStorage[keccak256("totalSpentPerDay", _day)] = _value;
}

function setTotalExecutedPerDay(uint256 _day, uint256 _value) private {
uintStorage[keccak256("totalExecutedPerDay", _day)] = _value;
}

function setWithdraws(bytes32 _withdraw, bool _status) private {
boolStorage[keccak256("withdraws", _withdraw)] = _status;
}
Expand Down
19 changes: 15 additions & 4 deletions deploy/src/foreign.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ const {
FOREIGN_MAX_AMOUNT_PER_TX,
FOREIGN_MIN_AMOUNT_PER_TX,
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS,

HOME_DAILY_LIMIT,
HOME_MAX_AMOUNT_PER_TX
} = process.env;

async function deployForeign() {
Expand Down Expand Up @@ -79,7 +80,7 @@ async function deployForeign() {
});
assert.equal(txInitializeForeign.status, '0x1', 'Transaction Failed');
const validatorOwner = await bridgeValidatorsForeign.methods.owner().call();
assert.equal(validatorOwner.toLowerCase(), FOREIGN_OWNER_MULTISIG.toLocaleLowerCase());
assert.equal(validatorOwner.toLocaleLowerCase(), FOREIGN_OWNER_MULTISIG.toLocaleLowerCase());
foreignNonce++;

console.log('\nTransferring ownership of ValidatorsProxy\n')
Expand Down Expand Up @@ -124,11 +125,21 @@ async function deployForeign() {
console.log(`Foreign Validators: ${storageValidatorsForeign.options.address},
FOREIGN_DAILY_LIMIT : ${FOREIGN_DAILY_LIMIT} which is ${Web3Utils.fromWei(FOREIGN_DAILY_LIMIT)} in eth,
FOREIGN_MAX_AMOUNT_PER_TX: ${FOREIGN_MAX_AMOUNT_PER_TX} which is ${Web3Utils.fromWei(FOREIGN_MAX_AMOUNT_PER_TX)} in eth,
FOREIGN_MIN_AMOUNT_PER_TX: ${FOREIGN_MIN_AMOUNT_PER_TX} which is ${Web3Utils.fromWei(FOREIGN_MIN_AMOUNT_PER_TX)} in eth
FOREIGN_MIN_AMOUNT_PER_TX: ${FOREIGN_MIN_AMOUNT_PER_TX} which is ${Web3Utils.fromWei(FOREIGN_MIN_AMOUNT_PER_TX)} in eth,
HOME_DAILY_LIMIT : ${HOME_DAILY_LIMIT} which is ${Web3Utils.fromWei(HOME_DAILY_LIMIT)} in eth,
HOME_MAX_AMOUNT_PER_TX: ${HOME_MAX_AMOUNT_PER_TX} which is ${Web3Utils.fromWei(HOME_MAX_AMOUNT_PER_TX)} in eth,
`)
foreignBridgeImplementation.options.address = foreignBridgeStorage.options.address
const initializeFBridgeData = await foreignBridgeImplementation.methods.initialize(
storageValidatorsForeign.options.address, poa20foreign.options.address, FOREIGN_DAILY_LIMIT, FOREIGN_MAX_AMOUNT_PER_TX, FOREIGN_MIN_AMOUNT_PER_TX, FOREIGN_GAS_PRICE, FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS
storageValidatorsForeign.options.address,
poa20foreign.options.address,
FOREIGN_DAILY_LIMIT,
FOREIGN_MAX_AMOUNT_PER_TX,
FOREIGN_MIN_AMOUNT_PER_TX,
FOREIGN_GAS_PRICE,
FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS,
HOME_DAILY_LIMIT,
HOME_MAX_AMOUNT_PER_TX
).encodeABI({from: DEPLOYMENT_ACCOUNT_ADDRESS});
const txInitializeBridge = await sendRawTx({
data: initializeFBridgeData,
Expand Down
15 changes: 13 additions & 2 deletions deploy/src/home.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const {
HOME_MAX_AMOUNT_PER_TX,
HOME_MIN_AMOUNT_PER_TX,
HOME_REQUIRED_BLOCK_CONFIRMATIONS,
FOREIGN_DAILY_LIMIT,
FOREIGN_MAX_AMOUNT_PER_TX
} = process.env;

async function deployHome()
Expand Down Expand Up @@ -113,11 +115,20 @@ async function deployHome()
HOME_DAILY_LIMIT : ${HOME_DAILY_LIMIT} which is ${Web3Utils.fromWei(HOME_DAILY_LIMIT)} in eth,
HOME_MAX_AMOUNT_PER_TX: ${HOME_MAX_AMOUNT_PER_TX} which is ${Web3Utils.fromWei(HOME_MAX_AMOUNT_PER_TX)} in eth,
HOME_MIN_AMOUNT_PER_TX: ${HOME_MIN_AMOUNT_PER_TX} which is ${Web3Utils.fromWei(HOME_MIN_AMOUNT_PER_TX)} in eth,
HOME_GAS_PRICE: ${HOME_GAS_PRICE}, HOME_REQUIRED_BLOCK_CONFIRMATIONS : ${HOME_REQUIRED_BLOCK_CONFIRMATIONS}
HOME_GAS_PRICE: ${HOME_GAS_PRICE}, HOME_REQUIRED_BLOCK_CONFIRMATIONS : ${HOME_REQUIRED_BLOCK_CONFIRMATIONS},
FOREIGN_DAILY_LIMIT : ${FOREIGN_DAILY_LIMIT} which is ${Web3Utils.fromWei(FOREIGN_DAILY_LIMIT)} in eth,
FOREIGN_MAX_AMOUNT_PER_TX: ${FOREIGN_MAX_AMOUNT_PER_TX} which is ${Web3Utils.fromWei(FOREIGN_MAX_AMOUNT_PER_TX)} in eth
`)
homeBridgeImplementation.options.address = homeBridgeStorage.options.address
const initializeHomeBridgeData = await homeBridgeImplementation.methods.initialize(
storageValidatorsHome.options.address, HOME_DAILY_LIMIT, HOME_MAX_AMOUNT_PER_TX, HOME_MIN_AMOUNT_PER_TX, HOME_GAS_PRICE, HOME_REQUIRED_BLOCK_CONFIRMATIONS
storageValidatorsHome.options.address,
HOME_DAILY_LIMIT,
HOME_MAX_AMOUNT_PER_TX,
HOME_MIN_AMOUNT_PER_TX,
HOME_GAS_PRICE,
HOME_REQUIRED_BLOCK_CONFIRMATIONS,
FOREIGN_DAILY_LIMIT,
FOREIGN_MAX_AMOUNT_PER_TX
).encodeABI({from: DEPLOYMENT_ACCOUNT_ADDRESS});
const txInitializeHomeBridge = await sendRawTx({
data: initializeHomeBridgeData,
Expand Down
7 changes: 5 additions & 2 deletions migrations/3_upgradeable_deployment.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,10 @@ module.exports = async function(deployer, network, accounts) {
MAX_AMOUNT_PER_TX,
MIN_AMOUNT_PER_TX,
HOME_GAS_PRICE,
HOME_REQUIRED_BLOCK_CONFIRMATIONS);
HOME_REQUIRED_BLOCK_CONFIRMATIONS,
foreignDailyLimit,
MAX_AMOUNT_PER_TX
);
await homeBridgeUpgradeable.upgradeTo('1', homeBridgeImplementation.address, {from: PROXY_OWNER});
await web3.eth.sendTransaction({
from: PROXY_OWNER,
Expand All @@ -75,7 +78,7 @@ module.exports = async function(deployer, network, accounts) {
var foreignBridgeWeb3 = web3.eth.contract(ForeignBridge.abi);
var foreignBridgeWeb3Instance = foreignBridgeWeb3.at(foreignBridgeImplementation.address);
var initializeDataForeign = foreignBridgeWeb3Instance.initialize
.getData(storageBridgeValidators.address, erc677token.address, foreignDailyLimit, MAX_AMOUNT_PER_TX, MIN_AMOUNT_PER_TX, FOREIGN_GAS_PRICE, FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS);
.getData(storageBridgeValidators.address, erc677token.address, foreignDailyLimit, MAX_AMOUNT_PER_TX, MIN_AMOUNT_PER_TX, FOREIGN_GAS_PRICE, FOREIGN_REQUIRED_BLOCK_CONFIRMATIONS, homeDailyLimit, MAX_AMOUNT_PER_TX);
await foreignBridgeUpgradeable.upgradeTo('1', foreignBridgeImplementation.address, {from: PROXY_OWNER});

await web3.eth.sendTransaction({
Expand Down
Loading

0 comments on commit 9623988

Please sign in to comment.