// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;
pragma abicoder v1;
/// @title A helper contract to manage nonce with the series
contract SeriesNonceManager {
error AdvanceNonceFailed();
event NonceIncreased(address indexed maker, uint256 series, uint256 newNonce);
// {
// 1: {
// '0x762f73Ad...842Ffa8': 0,
// '0xd20c41ee...32aaDe2': 1
// },
// 2: {
// '0x762f73Ad...842Ffa8': 3,
// '0xd20c41ee...32aaDe2': 15
// },
// ...
// }
mapping(uint256 => mapping(address => uint256)) public nonce;
/// @notice Advances nonce by one
function increaseNonce(uint8 series) external {
advanceNonce(series, 1);
}
/// @notice Advances nonce by specified amount
function advanceNonce(uint256 series, uint256 amount) public {
if (amount == 0 || amount > 255) revert AdvanceNonceFailed();
unchecked {
uint256 newNonce = nonce[series][msg.sender] + amount;
nonce[series][msg.sender] = newNonce;
emit NonceIncreased(msg.sender, series, newNonce);
}
}
/// @notice Checks if `makerAddress` has specified `makerNonce` for `series`
/// @return Result True if `makerAddress` has specified nonce. Otherwise, false
function nonceEquals(uint256 series, address makerAddress, uint256 makerNonce) public view returns(bool) {
return nonce[series][makerAddress] == makerNonce;
}
/// @notice Checks passed time against block timestamp
/// @return Result True if current block timestamp is lower than `time`. Otherwise, false
function timestampBelow(uint256 time) public view returns(bool) {
return block.timestamp < time; // solhint-disable-line not-rely-on-time
}
function timestampBelowAndNonceEquals(uint256 timeNonceSeriesAccount) external view returns(bool) {
uint256 _time = uint40(timeNonceSeriesAccount >> 216);
uint256 _nonce = uint40(timeNonceSeriesAccount >> 176);
uint256 _series = uint16(timeNonceSeriesAccount >> 160);
address _account = address(uint160(timeNonceSeriesAccount));
return timestampBelow(_time) && nonceEquals(_series, _account, _nonce);
}
}
{
"compilationTarget": {
"contracts/helpers/SeriesNonceManager.sol": "SeriesNonceManager"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 1000000
},
"remappings": []
}
[{"inputs":[],"name":"AdvanceNonceFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"maker","type":"address"},{"indexed":false,"internalType":"uint256","name":"series","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newNonce","type":"uint256"}],"name":"NonceIncreased","type":"event"},{"inputs":[{"internalType":"uint256","name":"series","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"advanceNonce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"series","type":"uint8"}],"name":"increaseNonce","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"nonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"series","type":"uint256"},{"internalType":"address","name":"makerAddress","type":"address"},{"internalType":"uint256","name":"makerNonce","type":"uint256"}],"name":"nonceEquals","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"time","type":"uint256"}],"name":"timestampBelow","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"timeNonceSeriesAccount","type":"uint256"}],"name":"timestampBelowAndNonceEquals","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]