Skip to content

Commit

Permalink
Introduce execution tracking into Modifier.sol based on executed and …
Browse files Browse the repository at this point in the history
…invalidated hashes
  • Loading branch information
cristovaoth committed Oct 12, 2023
1 parent c086848 commit 13b826e
Show file tree
Hide file tree
Showing 8 changed files with 283 additions and 76 deletions.
13 changes: 11 additions & 2 deletions contracts/core/GuardableModifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ abstract contract GuardableModifier is Module, Guardable, Modifier {
address(0),
payable(0),
"",
authorizer()
_authorizer()
);
}
success = IAvatar(target).execTransactionFromModule(
Expand Down Expand Up @@ -78,7 +78,7 @@ abstract contract GuardableModifier is Module, Guardable, Modifier {
address(0),
payable(0),
"",
authorizer()
_authorizer()
);
}

Expand All @@ -89,4 +89,13 @@ abstract contract GuardableModifier is Module, Guardable, Modifier {
IGuard(currentGuard).checkAfterExecution(bytes32(0), success);
}
}

function _authorizer() private returns (address) {
if (modules[msg.sender] != address(0)) {
return msg.sender;
}

(, address signer) = moduleTxSignedBy();
return signer;
}
}
41 changes: 26 additions & 15 deletions contracts/core/Modifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@
pragma solidity >=0.7.0 <0.9.0;

import "../interfaces/IAvatar.sol";
import "../signature/ExecutionTracker.sol";
import "../signature/SignatureChecker.sol";
import "./Module.sol";

/// @title Modifier Interface - A contract that sits between a Module and an Avatar and enforce some additional logic.
abstract contract Modifier is Module, SignatureChecker, IAvatar {
abstract contract Modifier is
Module,
ExecutionTracker,
SignatureChecker,
IAvatar
{
address internal constant SENTINEL_MODULES = address(0x1);
/// Mapping of modules.
mapping(address => address) internal modules;
Expand All @@ -15,6 +21,12 @@ abstract contract Modifier is Module, SignatureChecker, IAvatar {
/// @param sender The address of the sender.
error NotAuthorized(address sender);

/// @param hash already executed.
error HashAlreadyExecuted(bytes32 hash);

/// @param hash already executed.
error HashInvalidated(bytes32 hash);

/// `module` is invalid.
error InvalidModule(address module);

Expand Down Expand Up @@ -69,26 +81,25 @@ abstract contract Modifier is Module, SignatureChecker, IAvatar {
*/

modifier moduleOnly() {
address module = authorizer();
if (modules[msg.sender] == address(0)) {
(bytes32 hash, address signer) = moduleTxSignedBy();

if (module == address(0)) {
revert NotAuthorized(msg.sender);
}
if (modules[signer] == address(0)) {
revert NotAuthorized(msg.sender);
}

_;
}
if (executed[signer][hash]) {
revert HashAlreadyExecuted(hash);
}

function authorizer() internal returns (address) {
if (modules[msg.sender] != address(0)) {
return msg.sender;
}
if (invalidated[signer][hash]) {
revert HashInvalidated(hash);
}

(, address signer) = moduleTxSignedBy();
if (modules[signer] != address(0)) {
return signer;
executed[signer][hash] = true;
}

return address(0);
_;
}

/// @dev Disables a module on the modifier.
Expand Down
12 changes: 12 additions & 0 deletions contracts/signature/ExecutionTracker.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.8.0 <0.9.0;

/// @title ExecutionTracker - A contract that keeps track of executed and invalidated hashes
contract ExecutionTracker {
mapping(address => mapping(bytes32 => bool)) public executed;
mapping(address => mapping(bytes32 => bool)) public invalidated;

function invalidate(bytes32 hash) external {
invalidated[msg.sender][hash] = true;
}
}
8 changes: 4 additions & 4 deletions contracts/test/TestGuardableModifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ pragma solidity >=0.7.0 <0.9.0;
import "../core/GuardableModifier.sol";

contract TestGuardableModifier is GuardableModifier {
event executed(
event Executed(
address to,
uint256 value,
bytes data,
Enum.Operation operation,
bool success
);

event executedAndReturnedData(
event ExecutedAndReturnedData(
address to,
uint256 value,
bytes data,
Expand All @@ -39,7 +39,7 @@ contract TestGuardableModifier is GuardableModifier {
Enum.Operation operation
) public override moduleOnly returns (bool success) {
success = exec(to, value, data, operation);
emit executed(to, value, data, operation, success);
emit Executed(to, value, data, operation, success);
}

/// @dev Passes a transaction to the modifier, expects return data.
Expand All @@ -60,7 +60,7 @@ contract TestGuardableModifier is GuardableModifier {
returns (bool success, bytes memory returnData)
{
(success, returnData) = execAndReturnData(to, value, data, operation);
emit executedAndReturnedData(
emit ExecutedAndReturnedData(
to,
value,
data,
Expand Down
8 changes: 4 additions & 4 deletions contracts/test/TestModifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ pragma solidity >=0.7.0 <0.9.0;
import "../core/Modifier.sol";

contract TestModifier is Modifier {
event executed(
event Executed(
address to,
uint256 value,
bytes data,
Enum.Operation operation,
bool success
);

event executedAndReturnedData(
event ExecutedAndReturnedData(
address to,
uint256 value,
bytes data,
Expand All @@ -41,7 +41,7 @@ contract TestModifier is Modifier {
Enum.Operation operation
) public override moduleOnly returns (bool success) {
success = exec(to, value, data, operation);
emit executed(to, value, data, operation, success);
emit Executed(to, value, data, operation, success);
}

/// @dev Passes a transaction to the modifier, expects return data.
Expand All @@ -62,7 +62,7 @@ contract TestModifier is Modifier {
returns (bool success, bytes memory returnData)
{
(success, returnData) = execAndReturnData(to, value, data, operation);
emit executedAndReturnedData(
emit ExecutedAndReturnedData(
to,
value,
data,
Expand Down
Loading

0 comments on commit 13b826e

Please sign in to comment.