Skip to content

Commit

Permalink
[ENHANCEMENT] Updated SuperAdmin [DONE]
Browse files Browse the repository at this point in the history
  • Loading branch information
Ronnieraj37 committed Nov 19, 2024
1 parent fb36f01 commit aa90790
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 32 deletions.
2 changes: 0 additions & 2 deletions solidity/src/AccessRegistry/AccessRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@ abstract contract AccessRegistry is Context, SuperAdmin2Step, FallbackAdmin2Step
function _initializeAccessRegistry(address _superAdmin, address _fallbackAdmin)
internal
virtual
notZeroAddress(_superAdmin)
notZeroAddress(_fallbackAdmin)
{
_initializeSuperAdmin(_superAdmin);
_initializeFallbackAdmin(_fallbackAdmin);
Expand Down
44 changes: 18 additions & 26 deletions solidity/src/AccessRegistry/helpers/superAdmin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,8 @@ abstract contract SuperAdmin {
/// The choice of manual storage layout is to enable compatibility
/// with both regular and upgradeable contracts.
bytes32 internal constant _SUPERADMIN_SLOT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;

/// The superAdminship handover slot of `newSuperAdmin` is given by:
/// ```
/// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
/// let handoverSlot := keccak256(0x00, 0x20)
/// ```
/// It stores the expiry timestamp of the two-step superAdminship handover.
uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;
bytes32 internal constant _PENDINGADMIN_SLOT = 0xd7695d11a3816d58521df826e1b82703428b9d6f01a588416b40a4e02023deae;
bytes32 internal constant _HANDOVERTIME_SLOT_SEED = 0xe73258ffc050df54d85cbff7148c2a66fde0cd543a82a20fd5b44d963b48ed6e;

/* INTERNAL FUNCTIONS */
/// @dev Override to return true to make `_initializeSuperAdmin` prevent double-initialization.
Expand Down Expand Up @@ -164,9 +158,8 @@ abstract contract SuperAdmin {
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to `expires`.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, newSuperAdmin)
sstore(keccak256(0x0c, 0x20), expires)
sstore(_PENDINGADMIN_SLOT,newSuperAdmin)
sstore(_HANDOVERTIME_SLOT_SEED, expires)
// Emit the {OwnershipHandoverRequested} event.
log2(0, 0, _SUPERADMINSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
}
Expand All @@ -176,14 +169,13 @@ abstract contract SuperAdmin {
/// @notice Cancels any pending ownership handover request for a specified new super admin.
/// @dev This function uses inline assembly to reset the designated handover storage slot to zero,
/// effectively canceling the handover request.
/// @param newSuperAdmin The address of the designated new super admin whose handover request is to be canceled.
function cancelOwnershipHandover(address newSuperAdmin) public virtual onlySuperAdmin {
function cancelOwnershipHandover() public virtual onlySuperAdmin {
/// @solidity memory-safe-assembly
assembly {
let newSuperAdmin := sload(_PENDINGADMIN_SLOT)
// Compute and set the handover slot to 0.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, newSuperAdmin)
sstore(keccak256(0x0c, 0x20), 0)
sstore(_PENDINGADMIN_SLOT,0)
sstore(_HANDOVERTIME_SLOT_SEED, 0)
// Emit the {OwnershipHandoverCanceled} event.
log2(0, 0, _SUPERADMINSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, newSuperAdmin)
}
Expand All @@ -196,17 +188,18 @@ abstract contract SuperAdmin {
function acceptOwnershipHandover() public {
/// @solidity memory-safe-assembly
assembly {
// Compute and set the handover slot to 0.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, caller())
let handoverSlot := keccak256(0x0c, 0x20)
if iszero(eq(caller(), sload(_PENDINGADMIN_SLOT))) {
mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
revert(0x1c, 0x04)
}
// If the handover does not exist, or has expired.
if gt(timestamp(), sload(handoverSlot)) {
if gt(timestamp(), sload(_HANDOVERTIME_SLOT_SEED)) {
mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
revert(0x1c, 0x04)
}
// Set the handover slot to 0.
sstore(handoverSlot, 0)
sstore(_PENDINGADMIN_SLOT,0)
sstore(_HANDOVERTIME_SLOT_SEED, 0)
let newSuperAdmin := shr(96, shl(96, caller())) // Store the new value.
log3(0, 0, _SUPERADMINSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newSuperAdmin)
}
Expand All @@ -229,11 +222,10 @@ abstract contract SuperAdmin {
function superAdminshipHandoverExpiresAt(address pendingOwner) public view virtual returns (uint256 result) {
/// @solidity memory-safe-assembly
assembly {
// Compute the handover slot.
mstore(0x0c, _HANDOVER_SLOT_SEED)
mstore(0x00, pendingOwner)
if eq(pendingOwner, sload(_PENDINGADMIN_SLOT)) {
// Load the handover slot.
result := sload(keccak256(0x0c, 0x20))
result := sload(_HANDOVERTIME_SLOT_SEED)
}
}
}

Expand Down
12 changes: 10 additions & 2 deletions solidity/src/MultiSigWallet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ contract MultiSigWallet is Initializable, AccessRegistry, UUPSUpgradeable {
error TransactionIdNotExist();
error FunctionAlreadyExists();
error FunctionDoesNotExist();
error ZeroAmountTransaction();

// ========== INITIALIZATION ==========
constructor() {
Expand Down Expand Up @@ -193,8 +194,7 @@ contract MultiSigWallet is Initializable, AccessRegistry, UUPSUpgradeable {
* @param amount The amount of tokens to mint
* @return The transaction ID
*/
/// TODO: add modifiers for amount != 0
function createMintTransaction(address to, uint256 amount) external virtual notZeroAddress(to) returns (uint256) {
function createMintTransaction(address to, uint256 amount) external virtual notZeroAmount(amount) notZeroAddress(to) returns (uint256) {
return _createStandardTransaction(MINT_SELECTOR, abi.encode(to, amount));
}

Expand All @@ -207,6 +207,7 @@ contract MultiSigWallet is Initializable, AccessRegistry, UUPSUpgradeable {
function createBurnTransaction(address from, uint256 amount)
external
virtual
notZeroAmount(amount)
notZeroAddress(from)
returns (uint256)
{
Expand Down Expand Up @@ -448,6 +449,13 @@ contract MultiSigWallet is Initializable, AccessRegistry, UUPSUpgradeable {
_;
}

modifier notZeroAmount(uint amount){
if(amount == 0){
revert ZeroAmountTransaction();
}
_;
}

function tokenContract() public view returns (address token) {
assembly {
token := sload(TOKEN_CONTRACT_SLOT)
Expand Down
4 changes: 2 additions & 2 deletions solidity/test/SuperAdmin.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ contract SuperAdminTest is Test {

// Revoke super admin and check if it resets
vm.prank(oldAdmin);
superAdminMock.cancelOwnershipHandover(newAdmin);
superAdminMock.cancelOwnershipHandover();

vm.startPrank(newAdmin);
//should fail as adminship is accepted
Expand Down Expand Up @@ -94,6 +94,6 @@ contract SuperAdminTest is Test {
// Ensure oldAdmin no longer has control
vm.expectRevert();
vm.prank(oldAdmin);
superAdminMock.cancelOwnershipHandover(newAdmin);
superAdminMock.cancelOwnershipHandover();
}
}

0 comments on commit aa90790

Please sign in to comment.