Skip to content

Commit

Permalink
Merge 26a152e into b66a678
Browse files Browse the repository at this point in the history
  • Loading branch information
patitonar committed Jul 29, 2019
2 parents b66a678 + 26a152e commit 7de5566
Show file tree
Hide file tree
Showing 4 changed files with 303 additions and 54 deletions.
2 changes: 1 addition & 1 deletion contracts/upgradeable_contracts/BasicBridge.sol
Expand Up @@ -16,7 +16,7 @@ contract BasicBridge is EternalStorage, Validatable, Ownable, Upgradeable, Claim
event ExecutionDailyLimitChanged(uint256 newLimit);

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

function setGasPrice(uint256 _gasPrice) external onlyOwner {
Expand Down
32 changes: 24 additions & 8 deletions contracts/upgradeable_contracts/OverdrawManagement.sol
Expand Up @@ -4,28 +4,40 @@ import "../upgradeability/EternalStorage.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "./Upgradeable.sol";
import "./RewardableBridge.sol";
import "./BasicBridge.sol";

contract OverdrawManagement is EternalStorage, RewardableBridge, Upgradeable {
contract OverdrawManagement is EternalStorage, RewardableBridge, Upgradeable, BasicBridge {
using SafeMath for uint256;

event UserRequestForSignature(address recipient, uint256 value);
event AssetAboveLimitsFixed(bytes32 indexed transactionHash, uint256 value, uint256 remaining);

function fixAssetsAboveLimits(bytes32 txHash, bool unlockOnForeign) external onlyIfUpgradeabilityOwner {
function fixAssetsAboveLimits(bytes32 txHash, bool unlockOnForeign, uint256 valueToUnlock)
external
onlyIfUpgradeabilityOwner
{
require(!fixedAssets(txHash));
require(valueToUnlock <= maxPerTx());
address recipient;
uint256 value;
(recipient, value) = txAboveLimits(txHash);
require(recipient != address(0) && value > 0);
setOutOfLimitAmount(outOfLimitAmount().sub(value));
require(recipient != address(0) && value > 0 && value >= valueToUnlock);
setOutOfLimitAmount(outOfLimitAmount().sub(valueToUnlock));
uint256 pendingValue = value.sub(valueToUnlock);
setTxAboveLimitsValue(pendingValue, txHash);
emit AssetAboveLimitsFixed(txHash, valueToUnlock, pendingValue);
if (pendingValue == 0) {
setFixedAssets(txHash);
}
if (unlockOnForeign) {
address feeManager = feeManagerContract();
uint256 eventValue = valueToUnlock;
if (feeManager != address(0)) {
uint256 fee = calculateFee(value, false, feeManager, HOME_FEE);
value = value.sub(fee);
uint256 fee = calculateFee(valueToUnlock, false, feeManager, HOME_FEE);
eventValue = valueToUnlock.sub(fee);
}
emit UserRequestForSignature(recipient, value);
emit UserRequestForSignature(recipient, eventValue);
}
setFixedAssets(txHash);
}

function outOfLimitAmount() public view returns (uint256) {
Expand All @@ -47,6 +59,10 @@ contract OverdrawManagement is EternalStorage, RewardableBridge, Upgradeable {

function setTxAboveLimits(address _recipient, uint256 _value, bytes32 _txHash) internal {
addressStorage[keccak256(abi.encodePacked("txOutOfLimitRecipient", _txHash))] = _recipient;
setTxAboveLimitsValue(_value, _txHash);
}

function setTxAboveLimitsValue(uint256 _value, bytes32 _txHash) internal {
uintStorage[keccak256(abi.encodePacked("txOutOfLimitValue", _txHash))] = _value;
}

Expand Down
162 changes: 139 additions & 23 deletions test/erc_to_erc/home_bridge.test.js
Expand Up @@ -16,6 +16,7 @@ const { createMessage, sign, getEvents, ether, expectEventInLogs } = require('..
const minPerTx = ether('0.01')
const requireBlockConfirmations = 8
const gasPrice = web3.utils.toWei('1', 'gwei')
const quarterEther = ether('0.25')
const oneEther = ether('1')
const halfEther = ether('0.5')
const foreignDailyLimit = oneEther
Expand Down Expand Up @@ -896,7 +897,7 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
owner
).should.be.fulfilled
})
it('Should reduce outOfLimitAmount and not emit any event', async () => {
it('Should revert if value to unlock is bigger than max per transaction', async () => {
const recipient = accounts[5]
const value = oneEther
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'
Expand All @@ -909,14 +910,43 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
outOfLimitAmount.should.be.bignumber.equal(value)

const { logs } = await homeBridge.fixAssetsAboveLimits(transactionHash, false).should.be.fulfilled
await homeBridge.fixAssetsAboveLimits(transactionHash, false, value).should.be.rejectedWith(ERROR_MSG)
})
it('Should allow to partially reduce outOfLimitAmount and not emit UserRequestForSignature', async () => {
const recipient = accounts[5]
const value = oneEther
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'
const { logs: affirmationLogs } = await homeBridge.executeAffirmation(recipient, value, transactionHash, {
from: authorities[0]
}).should.be.fulfilled

affirmationLogs[0].event.should.be.equal('AmountLimitExceeded')

logs.length.should.be.equal(0)
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
outOfLimitAmount.should.be.bignumber.equal(value)

const newOutOfLimitAmount = await homeBridge.outOfLimitAmount()
newOutOfLimitAmount.should.be.bignumber.equal(ZERO)
const { logs } = await homeBridge.fixAssetsAboveLimits(transactionHash, false, halfEther).should.be.fulfilled

logs.length.should.be.equal(1)
expectEventInLogs(logs, 'AssetAboveLimitsFixed', {
transactionHash,
value: halfEther,
remaining: halfEther
})
expect(await homeBridge.outOfLimitAmount()).to.be.bignumber.equal(halfEther)

const { logs: logsSecondTx } = await homeBridge.fixAssetsAboveLimits(transactionHash, false, halfEther).should.be
.fulfilled

logsSecondTx.length.should.be.equal(1)
expectEventInLogs(logsSecondTx, 'AssetAboveLimitsFixed', {
transactionHash,
value: halfEther,
remaining: ZERO
})
expect(await homeBridge.outOfLimitAmount()).to.be.bignumber.equal(ZERO)
})
it('Should reduce outOfLimitAmount and emit UserRequestForSignature', async () => {
it('Should allow to partially reduce outOfLimitAmount and emit UserRequestForSignature', async () => {
const recipient = accounts[5]
const value = oneEther
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'
Expand All @@ -929,16 +959,95 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
outOfLimitAmount.should.be.bignumber.equal(value)

const { logs } = await homeBridge.fixAssetsAboveLimits(transactionHash, true).should.be.fulfilled
const { logs } = await homeBridge.fixAssetsAboveLimits(transactionHash, true, halfEther).should.be.fulfilled

logs.length.should.be.equal(1)
logs.length.should.be.equal(2)
expectEventInLogs(logs, 'AssetAboveLimitsFixed', {
transactionHash,
value: halfEther,
remaining: halfEther
})
expectEventInLogs(logs, 'UserRequestForSignature', {
recipient,
value
value: halfEther
})

const newOutOfLimitAmount = await homeBridge.outOfLimitAmount()
newOutOfLimitAmount.should.be.bignumber.equal(ZERO)
expect(await homeBridge.outOfLimitAmount()).to.be.bignumber.equal(halfEther)

const { logs: logsSecondTx } = await homeBridge.fixAssetsAboveLimits(transactionHash, true, halfEther).should.be
.fulfilled

logsSecondTx.length.should.be.equal(2)
expectEventInLogs(logsSecondTx, 'AssetAboveLimitsFixed', {
transactionHash,
value: halfEther,
remaining: ZERO
})
expectEventInLogs(logsSecondTx, 'UserRequestForSignature', {
recipient,
value: halfEther
})

expect(await homeBridge.outOfLimitAmount()).to.be.bignumber.equal(ZERO)
})
it('Should revert if try to unlock more than available', async () => {
const recipient = accounts[5]
const value = oneEther
const transactionHash = '0x806335163828a8eda675cff9c84fa6e6c7cf06bb44cc6ec832e42fe789d01415'
const { logs: affirmationLogs } = await homeBridge.executeAffirmation(recipient, value, transactionHash, {
from: authorities[0]
}).should.be.fulfilled

affirmationLogs[0].event.should.be.equal('AmountLimitExceeded')

const outOfLimitAmount = await homeBridge.outOfLimitAmount()
outOfLimitAmount.should.be.bignumber.equal(value)

const { logs } = await homeBridge.fixAssetsAboveLimits(transactionHash, true, halfEther).should.be.fulfilled

logs.length.should.be.equal(2)
expectEventInLogs(logs, 'AssetAboveLimitsFixed', {
transactionHash,
value: halfEther,
remaining: halfEther
})
expectEventInLogs(logs, 'UserRequestForSignature', {
recipient,
value: halfEther
})

expect(await homeBridge.outOfLimitAmount()).to.be.bignumber.equal(halfEther)

const { logs: logsSecondTx } = await homeBridge.fixAssetsAboveLimits(transactionHash, true, quarterEther).should
.be.fulfilled

logsSecondTx.length.should.be.equal(2)
expectEventInLogs(logsSecondTx, 'AssetAboveLimitsFixed', {
transactionHash,
value: quarterEther,
remaining: quarterEther
})
expectEventInLogs(logsSecondTx, 'UserRequestForSignature', {
recipient,
value: quarterEther
})

expect(await homeBridge.outOfLimitAmount()).to.be.bignumber.equal(quarterEther)

await homeBridge.fixAssetsAboveLimits(transactionHash, true, halfEther).should.be.rejectedWith(ERROR_MSG)
const { logs: logsThirdTx } = await homeBridge.fixAssetsAboveLimits(transactionHash, true, quarterEther).should.be
.fulfilled
expectEventInLogs(logsThirdTx, 'AssetAboveLimitsFixed', {
transactionHash,
value: quarterEther,
remaining: ZERO
})
expectEventInLogs(logsThirdTx, 'UserRequestForSignature', {
recipient,
value: quarterEther
})

expect(await homeBridge.outOfLimitAmount()).to.be.bignumber.equal(ZERO)
})
it('Should not be allow to be called by an already fixed txHash', async () => {
const recipient = accounts[5]
Expand All @@ -956,18 +1065,20 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
outOfLimitAmount.should.be.bignumber.equal(value.add(value))

await homeBridge.fixAssetsAboveLimits(transactionHash, false).should.be.fulfilled
await homeBridge.fixAssetsAboveLimits(transactionHash, false, halfEther).should.be.fulfilled
await homeBridge.fixAssetsAboveLimits(transactionHash, false, halfEther).should.be.fulfilled

const newOutOfLimitAmount = await homeBridge.outOfLimitAmount()
newOutOfLimitAmount.should.be.bignumber.equal(value)

await homeBridge.fixAssetsAboveLimits(transactionHash, false).should.be.rejectedWith(ERROR_MSG)
await homeBridge.fixAssetsAboveLimits(transactionHash2, false).should.be.fulfilled
await homeBridge.fixAssetsAboveLimits(transactionHash, false, halfEther).should.be.rejectedWith(ERROR_MSG)

await homeBridge.fixAssetsAboveLimits(transactionHash2, false, halfEther).should.be.fulfilled
await homeBridge.fixAssetsAboveLimits(transactionHash2, false, halfEther).should.be.fulfilled

const updatedOutOfLimitAmount = await homeBridge.outOfLimitAmount()
updatedOutOfLimitAmount.should.be.bignumber.equal(ZERO)
expect(await homeBridge.outOfLimitAmount()).to.be.bignumber.equal(ZERO)

await homeBridge.fixAssetsAboveLimits(transactionHash2, false).should.be.rejectedWith(ERROR_MSG)
await homeBridge.fixAssetsAboveLimits(transactionHash2, false, halfEther).should.be.rejectedWith(ERROR_MSG)
})
it('Should fail if txHash didnt increase out of limit amount', async () => {
const recipient = accounts[5]
Expand All @@ -981,7 +1092,7 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {

affirmationLogs[0].event.should.be.equal('AmountLimitExceeded')

await homeBridge.fixAssetsAboveLimits(invalidTxHash, true).should.be.rejectedWith(ERROR_MSG)
await homeBridge.fixAssetsAboveLimits(invalidTxHash, true, halfEther).should.be.rejectedWith(ERROR_MSG)
})
it('Should fail if not called by proxyOwner', async () => {
const recipient = accounts[5]
Expand All @@ -995,9 +1106,9 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
affirmationLogs[0].event.should.be.equal('AmountLimitExceeded')

await homeBridge
.fixAssetsAboveLimits(transactionHash, true, { from: recipient })
.fixAssetsAboveLimits(transactionHash, true, halfEther, { from: recipient })
.should.be.rejectedWith(ERROR_MSG)
await homeBridge.fixAssetsAboveLimits(transactionHash, true, { from: owner }).should.be.fulfilled
await homeBridge.fixAssetsAboveLimits(transactionHash, true, halfEther, { from: owner }).should.be.fulfilled
})
it('Should emit UserRequestForSignature with value reduced by fee', async () => {
const recipient = accounts[5]
Expand All @@ -1007,7 +1118,7 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const feeManager = await FeeManagerErcToErcPOSDAO.new()
const fee = 0.001
const feeInWei = ether(fee.toString())
const valueCalc = 1 - fee
const valueCalc = 0.5 * (1 - fee)
const finalValue = ether(valueCalc.toString())
await homeBridge.setFeeManagerContract(feeManager.address, { from: owner }).should.be.fulfilled
await homeBridge.setHomeFee(feeInWei, { from: owner }).should.be.fulfilled
Expand All @@ -1025,9 +1136,14 @@ contract('HomeBridge_ERC20_to_ERC20', async accounts => {
const outOfLimitAmount = await homeBridge.outOfLimitAmount()
outOfLimitAmount.should.be.bignumber.equal(value)

const { logs } = await homeBridge.fixAssetsAboveLimits(transactionHash, true).should.be.fulfilled
const { logs } = await homeBridge.fixAssetsAboveLimits(transactionHash, true, halfEther).should.be.fulfilled

logs.length.should.be.equal(1)
logs.length.should.be.equal(2)
expectEventInLogs(logs, 'AssetAboveLimitsFixed', {
transactionHash,
value: halfEther,
remaining: halfEther
})
expectEventInLogs(logs, 'UserRequestForSignature', {
recipient,
value: finalValue
Expand Down

0 comments on commit 7de5566

Please sign in to comment.