-
Notifications
You must be signed in to change notification settings - Fork 859
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
528 additions
and
295 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// SPDX-License-Identifier: LGPL-3.0-only | ||
pragma solidity >=0.7.0 <0.9.0; | ||
|
||
import {SafeStorage} from "../libraries/SafeStorage.sol"; | ||
import {Guard} from "../base/GuardManager.sol"; | ||
import "hardhat/console.sol"; | ||
|
||
interface ISafe { | ||
function setFallbackHandler(address handler) external; | ||
|
||
function setGuard(address guard) external; | ||
} | ||
|
||
/** | ||
* @title Migration Contract for Safe Upgrade | ||
* @notice This contract facilitates the migration of a Safe contract from version 1.3.0/1.4.1 to 1.5.0. | ||
*/ | ||
contract Safe150Migration is SafeStorage { | ||
// Address of this contract | ||
address public immutable MIGRATION_SINGLETON; | ||
|
||
// Address of Safe contract version 1.5.0 Singleton | ||
address public constant SAFE_150_SINGLETON = address(0x88627c8904eCd9DF96A572Ef32A7ff13b199Ed8D); | ||
|
||
// Address of Safe contract version 1.5.0 Singleton (L2) | ||
address public constant SAFE_150_SINGLETON_L2 = address(0x0Ee37514644683f7EB9745a5726C722DeBa77e52); | ||
|
||
// Address of Safe contract version 1.5.0 Compatibility Fallback Handler | ||
address public constant SAFE_150_FALLBACK_HANDLER = address(0x8aa755cB169991fEDC3E306751dCb71964A041c7); | ||
|
||
bytes32 internal constant GUARD_STORAGE_SLOT = 0x4a204f620c8c5ccdca3fd54d003badd85ba500436a431f0cbda4f558c93c34c8; | ||
|
||
/** | ||
* @notice Constructor | ||
* @dev Initializes the migrationSingleton with the contract's own address. | ||
*/ | ||
constructor() { | ||
MIGRATION_SINGLETON = address(this); | ||
} | ||
|
||
/** | ||
* @notice Event indicating a change of master copy address. | ||
* @param singleton New master copy address | ||
*/ | ||
event ChangedMasterCopy(address singleton); | ||
|
||
function checkGuard() private view { | ||
address guard = getGuard(); | ||
console.log("guard: %s", guard); | ||
if (guard != address(0)) { | ||
require(Guard(guard).supportsInterface(type(Guard).interfaceId), "GS300"); | ||
} | ||
} | ||
|
||
/** | ||
* @notice Migrate to Safe 1.5.0 Singleton (L1) at `safe150Singleton` | ||
* @dev This function should only be called via a delegatecall to perform the upgrade. | ||
*/ | ||
function migrate() public { | ||
require(address(this) != MIGRATION_SINGLETON, "Migration should only be called via delegatecall"); | ||
|
||
checkGuard(); | ||
|
||
singleton = SAFE_150_SINGLETON; | ||
ISafe(address(this)).setFallbackHandler(SAFE_150_FALLBACK_HANDLER); | ||
emit ChangedMasterCopy(singleton); | ||
} | ||
|
||
function migrateWithSetGuard(address guard) public { | ||
require(address(this) != MIGRATION_SINGLETON, "Migration should only be called via delegatecall"); | ||
|
||
ISafe safe = ISafe(address(this)); | ||
|
||
singleton = SAFE_150_SINGLETON; | ||
|
||
safe.setGuard(guard); | ||
safe.setFallbackHandler(SAFE_150_FALLBACK_HANDLER); | ||
|
||
emit ChangedMasterCopy(singleton); | ||
} | ||
|
||
/** | ||
* @notice Migrate to Safe 1.5.0 Singleton (L2) at `safe150SingletonL2` | ||
* @dev This function should only be called via a delegatecall to perform the upgrade. | ||
*/ | ||
function migrateL2() public { | ||
require(address(this) != MIGRATION_SINGLETON, "Migration should only be called via delegatecall"); | ||
|
||
checkGuard(); | ||
|
||
singleton = SAFE_150_SINGLETON_L2; | ||
ISafe(address(this)).setFallbackHandler(SAFE_150_FALLBACK_HANDLER); | ||
emit ChangedMasterCopy(singleton); | ||
} | ||
|
||
function migrateL2WithSetGuard(address guard) public { | ||
require(address(this) != MIGRATION_SINGLETON, "Migration should only be called via delegatecall"); | ||
|
||
ISafe safe = ISafe(address(this)); | ||
|
||
singleton = SAFE_150_SINGLETON_L2; | ||
|
||
safe.setGuard(guard); | ||
safe.setFallbackHandler(SAFE_150_FALLBACK_HANDLER); | ||
|
||
emit ChangedMasterCopy(singleton); | ||
} | ||
|
||
function getGuard() internal view returns (address guard) { | ||
bytes32 slot = GUARD_STORAGE_SLOT; | ||
// solhint-disable-next-line no-inline-assembly | ||
/// @solidity memory-safe-assembly | ||
assembly { | ||
guard := sload(slot) | ||
} | ||
} | ||
} |
Oops, something went wrong.