-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: IndexingMath, Proxy, Migratable (#38)
- Loading branch information
1 parent
f337029
commit c995528
Showing
35 changed files
with
313 additions
and
39 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 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 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 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,61 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
pragma solidity >=0.8.20 <0.9.0; | ||
|
||
import { IMigratable } from "./interfaces/IMigratable.sol"; | ||
|
||
/** | ||
* @title Abstract implementation for exposing the ability to migrate a contract, extending ERC-1967. | ||
* @author M^0 Labs | ||
*/ | ||
abstract contract Migratable is IMigratable { | ||
/* ============ Variables ============ */ | ||
|
||
/// @dev Storage slot with the address of the current factory. `keccak256('eip1967.proxy.implementation') - 1`. | ||
uint256 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; | ||
|
||
/* ============ Interactive Functions ============ */ | ||
|
||
/// @inheritdoc IMigratable | ||
function migrate() external { | ||
_migrate(_getMigrator()); | ||
} | ||
|
||
/* ============ View/Pure Functions ============ */ | ||
|
||
/// @inheritdoc IMigratable | ||
function implementation() public view returns (address implementation_) { | ||
assembly { | ||
implementation_ := sload(_IMPLEMENTATION_SLOT) | ||
} | ||
} | ||
|
||
/* ============ Internal Interactive Functions ============ */ | ||
|
||
/** | ||
* @dev Performs an arbitrary migration by delegate-calling `migrator_`. | ||
* @param migrator_ The address of a migrator contract. | ||
*/ | ||
function _migrate(address migrator_) internal { | ||
if (migrator_ == address(0)) revert ZeroMigrator(); | ||
|
||
if (migrator_.code.length == 0) revert InvalidMigrator(); | ||
|
||
address oldImplementation_ = implementation(); | ||
|
||
(bool success_, ) = migrator_.delegatecall(""); | ||
if (!success_) revert MigrationFailed(); | ||
|
||
address newImplementation_ = implementation(); | ||
|
||
emit Migrated(migrator_, oldImplementation_, newImplementation_); | ||
|
||
// NOTE: Redundant event emitted to conform to the EIP-1967 standard. | ||
emit Upgraded(newImplementation_); | ||
} | ||
|
||
/* ============ Internal View/Pure Functions ============ */ | ||
|
||
/// @dev Returns the address of a migrator contract. | ||
function _getMigrator() internal view virtual returns (address); | ||
} |
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,48 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
pragma solidity >=0.8.20 <0.9.0; | ||
|
||
/** | ||
* @title Minimal transparent proxy. | ||
* @author M^0 Labs | ||
*/ | ||
contract Proxy { | ||
/// @dev Storage slot with the address of the current factory. `keccak256('eip1967.proxy.implementation') - 1`. | ||
uint256 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; | ||
|
||
/** | ||
* @dev Constructs the contract given the address of some implementation. | ||
* @param implementation_ The address of some implementation. | ||
*/ | ||
constructor(address implementation_) { | ||
if (implementation_ == address(0)) revert(); | ||
|
||
assembly { | ||
sstore(_IMPLEMENTATION_SLOT, implementation_) | ||
} | ||
} | ||
|
||
fallback() external payable virtual { | ||
bytes32 implementation_; | ||
|
||
assembly { | ||
implementation_ := sload(_IMPLEMENTATION_SLOT) | ||
} | ||
|
||
assembly { | ||
calldatacopy(0, 0, calldatasize()) | ||
|
||
let result_ := delegatecall(gas(), implementation_, 0, calldatasize(), 0, 0) | ||
|
||
returndatacopy(0, 0, returndatasize()) | ||
|
||
switch result_ | ||
case 0 { | ||
revert(0, returndatasize()) | ||
} | ||
default { | ||
return(0, returndatasize()) | ||
} | ||
} | ||
} | ||
} |
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 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 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 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 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 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 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 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,44 @@ | ||
// SPDX-License-Identifier: GPL-3.0 | ||
|
||
pragma solidity >=0.8.20 <0.9.0; | ||
|
||
/** | ||
* @title Interface for exposing the ability to migrate a contract, extending the ERC-1967 interface. | ||
* @author M^0 Labs | ||
*/ | ||
interface IMigratable { | ||
/* ============ Events ============ */ | ||
|
||
/** | ||
* @notice Emitted when a migration to a new implementation is performed. | ||
* @param migrator The address that performed the migration. | ||
* @param oldImplementation The address of the old implementation. | ||
* @param newImplementation The address of the new implementation. | ||
*/ | ||
event Migrated(address indexed migrator, address indexed oldImplementation, address indexed newImplementation); | ||
|
||
/** | ||
* @notice Emitted when the implementation address for the proxy is changed. | ||
* @param implementation The address of the new implementation for the proxy. | ||
*/ | ||
event Upgraded(address indexed implementation); | ||
|
||
/// @notice Emitted when calling `stopEarning` for an account approved as earner by the Registrar. | ||
error InvalidMigrator(); | ||
|
||
/// @notice Emitted when the delegatecall to a migrator fails. | ||
error MigrationFailed(); | ||
|
||
/// @notice Emitted when the zero address is passed as a migrator. | ||
error ZeroMigrator(); | ||
|
||
/* ============ Interactive Functions ============ */ | ||
|
||
/// @notice Performs an arbitrarily defined migration. | ||
function migrate() external; | ||
|
||
/* ============ View/Pure Functions ============ */ | ||
|
||
/// @notice Returns the address of the current implementation contract. | ||
function implementation() external view returns (address); | ||
} |
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 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 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
Oops, something went wrong.