Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cron fix #29

Merged
merged 23 commits into from
Nov 6, 2023
Merged
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: tests post cron refactor
  • Loading branch information
xBalbinus committed Nov 2, 2023
commit 18af3bed01da92a1ee4def3818c1cf8a79f32471
123 changes: 74 additions & 49 deletions src/lamination/LaminatedProxy.sol
Original file line number Diff line number Diff line change
@@ -8,8 +8,9 @@ import "openzeppelin/security/ReentrancyGuard.sol";
contract LaminatedProxy is LaminatedStorage, ReentrancyGuard {
/// @notice The map from sequence number to calls held in the mempool.
mapping(uint256 => CallObjectHolder) public deferredCalls;

/// @notice The sequence number of the currently executing call.
uint256 _executingSequenceNumber;
/// @notice A flag indicating whether a sequence number is currently being executed.
bool _executingSequenceNumberSet;

/// @notice Some functions must be called by the laminator or the proxy only.
@@ -20,6 +21,10 @@ contract LaminatedProxy is LaminatedStorage, ReentrancyGuard {
/// @dev Selector 0x91c58dcd
error NotLaminator();

/// @notice Some functions must be called by the laminator or the proxy only.
/// @dev Selector 0xbf10dd3a
error NotProxy();

/// @notice Calls pulled from the mempool must have been previously pushed and initialized.
/// @dev Selector 0x1c72fad4
error Uninitialized();
@@ -32,6 +37,9 @@ contract LaminatedProxy is LaminatedStorage, ReentrancyGuard {
/// @dev Selector 0x3204506f
error CallFailed();

/// @notice The sequence number of a deferred call must be set before it can be executed.
error SeqNumberNotSet();

/// @dev Emitted when a function call is deferred and added to the queue.
/// @param callObjs The CallObject[] containing details of the deferred function call.
/// @param sequenceNumber The sequence number assigned to the deferred function call.
@@ -51,11 +59,11 @@ contract LaminatedProxy is LaminatedStorage, ReentrancyGuard {
/// @param currentBlock The current block number.
event CallableBlock(uint256 callableBlock, uint256 currentBlock);

/// @dev Modifier to make a function callable only by the laminator or proxy.
/// Reverts the transaction if the sender is not the laminator or proxy.
modifier onlyLaminatorOrProxy() {
if (msg.sender != address(laminator()) && msg.sender != address(this)) {
revert NotLaminatorOrProxy();
/// @dev Modifier to make a function callable only by the proxy.
/// Reverts the transaction if the sender is not the proxy.
modifier onlyProxy() {
if (msg.sender != address(this)) {
revert NotProxy();
}
_;
}
@@ -69,6 +77,15 @@ contract LaminatedProxy is LaminatedStorage, ReentrancyGuard {
_;
}

/// @dev Modifier to make a function callable only by the laminator or proxy.
/// Reverts the transaction if the sender is not the laminator or proxy.
modifier onlyLaminatorOrProxy() {
if (msg.sender != address(laminator()) && msg.sender != address(this)) {
revert NotLaminatorOrProxy();
}
_;
}

/// @notice Views a deferred function call with a given sequence number.
/// @dev Returns a tuple containing a boolean indicating whether the deferred call exists,
/// and the CallObject containing details of the deferred function call.
@@ -93,6 +110,46 @@ contract LaminatedProxy is LaminatedStorage, ReentrancyGuard {
/// @dev The received Ether can be spent via the `execute`, `push`, and `pull` functions.
receive() external payable {}

function copyCurrentJob(uint256 delay, bytes memory shouldCopy) public returns (uint256) {
if (!_executingSequenceNumberSet) {
revert SeqNumberNotSet();
}
return copyJob(_executingSequenceNumber, delay, shouldCopy);
}

function copyJob(uint256 seqNumber, uint256 delay, bytes memory shouldCopy) public returns (uint256) {
if (msg.sender != address(this)) {
revert NotProxy();
}

if (shouldCopy.length != 0) {
CallObject memory callObj = abi.decode(shouldCopy, (CallObject));
bytes memory result = _executeSingle(callObj);
bool shouldContinue = abi.decode(result, (bool));
if (!shouldContinue) {
return 0;
}
}

CallObjectHolder memory coh = deferredCalls[seqNumber];
if (!coh.initialized) {
revert Uninitialized();
}
CallObject[] memory callObjs = coh.callObjs;
uint256 callSequenceNumber = count();
CallObjectHolder storage holder = deferredCalls[callSequenceNumber];
holder.initialized = true;
holder.firstCallableBlock = block.number + delay;
for (uint256 i = 0; i < callObjs.length; ++i) {
holder.callObjs.push(callObjs[i]);
}

emit CallableBlock(block.number, block.number);
emit CallPushed(callObjs, callSequenceNumber);
_incrementSequenceNumber();
return callSequenceNumber;
}

/// @notice Pushes a deferred function call to be executed after a certain delay.
/// @dev Adds a new CallObject to the `deferredCalls` mapping and emits a CallPushed event.
/// The function can only be called by the Laminator or the LaminatedProxy contract itself.
@@ -120,11 +177,6 @@ contract LaminatedProxy is LaminatedStorage, ReentrancyGuard {
_incrementSequenceNumber();
}

function getExecutingSequenceNumber() external returns (uint256) {
require(_executingSequenceNumberSet, "No executing sequence number set");
return _executingSequenceNumber;
}

/// @notice Executes a deferred function call that has been pushed to the contract.
/// @dev Executes the deferred call specified by the sequence number `seqNumber`.
/// This function performs a series of checks before calling `_execute` to
@@ -151,44 +203,6 @@ contract LaminatedProxy is LaminatedStorage, ReentrancyGuard {
_executingSequenceNumberSet = false;
}

function copyJob(uint256 seqNumber, uint256 delay, bytes memory shouldCopy) public returns (uint256) {
require(msg.sender == address(this), "Only this contract can call this function");

if (shouldCopy.length != 0) {
CallObject memory callObj = abi.decode(shouldCopy, (CallObject));
bytes memory result = _executeSingle(callObj);
bool shouldContinue = abi.decode(result, (bool));
if (!shouldContinue) {
return 0;
}
}

CallObjectHolder memory coh = deferredCalls[seqNumber];
if (!coh.initialized) {
revert Uninitialized();
}
CallObject[] memory callObjs = coh.callObjs;
uint256 callSequenceNumber = count();
CallObjectHolder storage holder = deferredCalls[callSequenceNumber];
holder.initialized = true;
holder.firstCallableBlock = block.number + delay;
for (uint256 i = 0; i < callObjs.length; ++i) {
holder.callObjs.push(callObjs[i]);
}

emit CallableBlock(block.number, block.number);
emit CallPushed(callObjs, callSequenceNumber);
_incrementSequenceNumber();
return callSequenceNumber;
}

function copyCurrentJob(uint256 delay, bytes memory shouldCopy) public returns (uint256) {
if (!_executingSequenceNumberSet) {
revert("No executing sequence number set");
}
return copyJob(_executingSequenceNumber, delay, shouldCopy);
}

/// @notice Executes a function call immediately.
/// @dev Decodes the provided `input` into a CallObject and then calls `_execute`.
/// Can only be invoked by the owner of the contract.
@@ -199,6 +213,17 @@ contract LaminatedProxy is LaminatedStorage, ReentrancyGuard {
return _execute(callsToMake);
}

/// @notice Returns the sequence number of the currently executing call.
/// @dev This function can only be called when a sequence number is currently being executed.
/// It reverts if no sequence number is set.
/// @return The sequence number of the currently executing call.
function getExecutingSequenceNumber() external view returns (uint256) {
if(!_executingSequenceNumberSet) {
revert SeqNumberNotSet();
}
return _executingSequenceNumber;
}

/// @dev Executes the function call specified by the CallObject `callToMake`.
/// Emits a `CallExecuted` event upon successful execution.
/// @param callsToMake The CallObject containing information about the function call to execute.