132 lines
5.5 KiB
Solidity
132 lines
5.5 KiB
Solidity
pragma solidity 0.4.24;
|
|
|
|
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
|
|
import "../upgradeability/EternalStorage.sol";
|
|
import "./DecimalShiftBridge.sol";
|
|
import "./Ownable.sol";
|
|
|
|
contract BasicTokenBridge is EternalStorage, Ownable, DecimalShiftBridge {
|
|
using SafeMath for uint256;
|
|
|
|
event DailyLimitChanged(uint256 newLimit);
|
|
event ExecutionDailyLimitChanged(uint256 newLimit);
|
|
|
|
bytes32 internal constant MIN_PER_TX = 0xbbb088c505d18e049d114c7c91f11724e69c55ad6c5397e2b929e68b41fa05d1; // keccak256(abi.encodePacked("minPerTx"))
|
|
bytes32 internal constant MAX_PER_TX = 0x0f8803acad17c63ee38bf2de71e1888bc7a079a6f73658e274b08018bea4e29c; // keccak256(abi.encodePacked("maxPerTx"))
|
|
bytes32 internal constant DAILY_LIMIT = 0x4a6a899679f26b73530d8cf1001e83b6f7702e04b6fdb98f3c62dc7e47e041a5; // keccak256(abi.encodePacked("dailyLimit"))
|
|
bytes32 internal constant EXECUTION_MAX_PER_TX = 0xc0ed44c192c86d1cc1ba51340b032c2766b4a2b0041031de13c46dd7104888d5; // keccak256(abi.encodePacked("executionMaxPerTx"))
|
|
bytes32 internal constant EXECUTION_DAILY_LIMIT = 0x21dbcab260e413c20dc13c28b7db95e2b423d1135f42bb8b7d5214a92270d237; // keccak256(abi.encodePacked("executionDailyLimit"))
|
|
|
|
function totalSpentPerDay(uint256 _day) public view returns (uint256) {
|
|
return uintStorage[keccak256(abi.encodePacked("totalSpentPerDay", _day))];
|
|
}
|
|
|
|
function totalExecutedPerDay(uint256 _day) public view returns (uint256) {
|
|
return uintStorage[keccak256(abi.encodePacked("totalExecutedPerDay", _day))];
|
|
}
|
|
|
|
function dailyLimit() public view returns (uint256) {
|
|
return uintStorage[DAILY_LIMIT];
|
|
}
|
|
|
|
function executionDailyLimit() public view returns (uint256) {
|
|
return uintStorage[EXECUTION_DAILY_LIMIT];
|
|
}
|
|
|
|
function maxPerTx() public view returns (uint256) {
|
|
return uintStorage[MAX_PER_TX];
|
|
}
|
|
|
|
function executionMaxPerTx() public view returns (uint256) {
|
|
return uintStorage[EXECUTION_MAX_PER_TX];
|
|
}
|
|
|
|
function minPerTx() public view returns (uint256) {
|
|
return uintStorage[MIN_PER_TX];
|
|
}
|
|
|
|
function withinLimit(uint256 _amount) public view returns (bool) {
|
|
uint256 nextLimit = totalSpentPerDay(getCurrentDay()).add(_amount);
|
|
return dailyLimit() >= nextLimit && _amount <= maxPerTx() && _amount >= minPerTx();
|
|
}
|
|
|
|
function withinExecutionLimit(uint256 _amount) public view returns (bool) {
|
|
uint256 nextLimit = totalExecutedPerDay(getCurrentDay()).add(_amount);
|
|
return executionDailyLimit() >= nextLimit && _amount <= executionMaxPerTx();
|
|
}
|
|
|
|
function getCurrentDay() public view returns (uint256) {
|
|
return now / 1 days;
|
|
}
|
|
|
|
function addTotalSpentPerDay(uint256 _day, uint256 _value) internal {
|
|
uintStorage[keccak256(abi.encodePacked("totalSpentPerDay", _day))] = totalSpentPerDay(_day).add(_value);
|
|
}
|
|
|
|
function addTotalExecutedPerDay(uint256 _day, uint256 _value) internal {
|
|
uintStorage[keccak256(abi.encodePacked("totalExecutedPerDay", _day))] = totalExecutedPerDay(_day).add(_value);
|
|
}
|
|
|
|
function setDailyLimit(uint256 _dailyLimit) external onlyOwner {
|
|
require(_dailyLimit > maxPerTx() || _dailyLimit == 0);
|
|
uintStorage[DAILY_LIMIT] = _dailyLimit;
|
|
emit DailyLimitChanged(_dailyLimit);
|
|
}
|
|
|
|
function setExecutionDailyLimit(uint256 _dailyLimit) external onlyOwner {
|
|
require(_dailyLimit > executionMaxPerTx() || _dailyLimit == 0);
|
|
uintStorage[EXECUTION_DAILY_LIMIT] = _dailyLimit;
|
|
emit ExecutionDailyLimitChanged(_dailyLimit);
|
|
}
|
|
|
|
function setExecutionMaxPerTx(uint256 _maxPerTx) external onlyOwner {
|
|
require(_maxPerTx < executionDailyLimit());
|
|
uintStorage[EXECUTION_MAX_PER_TX] = _maxPerTx;
|
|
}
|
|
|
|
function setMaxPerTx(uint256 _maxPerTx) external onlyOwner {
|
|
require(_maxPerTx == 0 || (_maxPerTx > minPerTx() && _maxPerTx < dailyLimit()));
|
|
uintStorage[MAX_PER_TX] = _maxPerTx;
|
|
}
|
|
|
|
function setMinPerTx(uint256 _minPerTx) external onlyOwner {
|
|
require(_minPerTx > 0 && _minPerTx < dailyLimit() && _minPerTx < maxPerTx());
|
|
uintStorage[MIN_PER_TX] = _minPerTx;
|
|
}
|
|
|
|
/**
|
|
* @dev Retrieves maximum available bridge amount per one transaction taking into account maxPerTx() and dailyLimit() parameters.
|
|
* @return minimum of maxPerTx parameter and remaining daily quota.
|
|
*/
|
|
function maxAvailablePerTx() public view returns (uint256) {
|
|
uint256 _maxPerTx = maxPerTx();
|
|
uint256 _dailyLimit = dailyLimit();
|
|
uint256 _spent = totalSpentPerDay(getCurrentDay());
|
|
uint256 _remainingOutOfDaily = _dailyLimit > _spent ? _dailyLimit - _spent : 0;
|
|
return _maxPerTx < _remainingOutOfDaily ? _maxPerTx : _remainingOutOfDaily;
|
|
}
|
|
|
|
function _setLimits(uint256[3] _limits) internal {
|
|
require(
|
|
_limits[2] > 0 && // minPerTx > 0
|
|
_limits[1] > _limits[2] && // maxPerTx > minPerTx
|
|
_limits[0] > _limits[1] // dailyLimit > maxPerTx
|
|
);
|
|
|
|
uintStorage[DAILY_LIMIT] = _limits[0];
|
|
uintStorage[MAX_PER_TX] = _limits[1];
|
|
uintStorage[MIN_PER_TX] = _limits[2];
|
|
|
|
emit DailyLimitChanged(_limits[0]);
|
|
}
|
|
|
|
function _setExecutionLimits(uint256[2] _limits) internal {
|
|
require(_limits[1] < _limits[0]); // foreignMaxPerTx < foreignDailyLimit
|
|
|
|
uintStorage[EXECUTION_DAILY_LIMIT] = _limits[0];
|
|
uintStorage[EXECUTION_MAX_PER_TX] = _limits[1];
|
|
|
|
emit ExecutionDailyLimitChanged(_limits[0]);
|
|
}
|
|
}
|