Skip to content
New issue

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

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

Already on GitHub? # to your account

feat: IndexingMath, Proxy, Migratable #38

Merged
merged 1 commit into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion src/ERC20Extended.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

import { IERC20 } from "./interfaces/IERC20.sol";
import { IERC20Extended } from "./interfaces/IERC20Extended.sol";
Expand Down
2 changes: 1 addition & 1 deletion src/ERC3009.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

import { IERC3009 } from "./interfaces/IERC3009.sol";

Expand Down
2 changes: 1 addition & 1 deletion src/ERC712Extended.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

import { IERC712 } from "./interfaces/IERC712.sol";
import { IERC712Extended } from "./interfaces/IERC712Extended.sol";
Expand Down
61 changes: 61 additions & 0 deletions src/Migratable.sol
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);
}
48 changes: 48 additions & 0 deletions src/Proxy.sol
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())
}
}
}
}
2 changes: 1 addition & 1 deletion src/StatefulERC712.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

import { IStatefulERC712 } from "./interfaces/IStatefulERC712.sol";

Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/IERC1271.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

/**
* @title Standard Signature Validation Method for Contracts via EIP-1271.
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/IERC20.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

/**
* @title ERC20 Token Standard.
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/IERC20Extended.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

import { IERC20 } from "./IERC20.sol";
import { IERC3009 } from "./IERC3009.sol";
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/IERC3009.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

import { IStatefulERC712 } from "./IStatefulERC712.sol";

Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/IERC712.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

/**
* @title Typed structured data hashing and signing via EIP-712.
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/IERC712Extended.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

import { IERC712 } from "./IERC712.sol";

Expand Down
44 changes: 44 additions & 0 deletions src/interfaces/IMigratable.sol
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);
}
2 changes: 1 addition & 1 deletion src/interfaces/IStatefulERC712.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

import { IERC712Extended } from "./IERC712Extended.sol";

Expand Down
2 changes: 1 addition & 1 deletion src/libs/Bytes32String.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

/**
* @title A library to convert between string and bytes32 (assuming 32 characters or less).
Expand Down
42 changes: 33 additions & 9 deletions src/libs/ContractHelper.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity 0.8.26;
pragma solidity >=0.8.20 <0.9.0;

// solhint-disable max-line-length

Expand Down Expand Up @@ -35,14 +35,38 @@ library ContractHelper {
nonce_ == 0x00
? abi.encodePacked(bytes1(0xd6), bytes1(0x94), account_, bytes1(0x80))
: nonce_ <= 0x7f
? abi.encodePacked(bytes1(0xd6), bytes1(0x94), account_, uint8(nonce_))
: nonce_ <= 0xff
? abi.encodePacked(bytes1(0xd7), bytes1(0x94), account_, bytes1(0x81), uint8(nonce_))
: nonce_ <= 0xffff
? abi.encodePacked(bytes1(0xd8), bytes1(0x94), account_, bytes1(0x82), uint16(nonce_))
: nonce_ <= 0xffffff
? abi.encodePacked(bytes1(0xd9), bytes1(0x94), account_, bytes1(0x83), uint24(nonce_))
: abi.encodePacked(bytes1(0xda), bytes1(0x94), account_, bytes1(0x84), uint32(nonce_))
? abi.encodePacked(bytes1(0xd6), bytes1(0x94), account_, uint8(nonce_))
: nonce_ <= 0xff
? abi.encodePacked(
bytes1(0xd7),
bytes1(0x94),
account_,
bytes1(0x81),
uint8(nonce_)
)
: nonce_ <= 0xffff
? abi.encodePacked(
bytes1(0xd8),
bytes1(0x94),
account_,
bytes1(0x82),
uint16(nonce_)
)
: nonce_ <= 0xffffff
? abi.encodePacked(
bytes1(0xd9),
bytes1(0x94),
account_,
bytes1(0x83),
uint24(nonce_)
)
: abi.encodePacked(
bytes1(0xda),
bytes1(0x94),
account_,
bytes1(0x84),
uint32(nonce_)
)
)
)
)
Expand Down
Loading
Loading