-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
create associated systems module (#1043)
* create associated systems module * created `AssociatedSystemsModule` which is sort of like a modernized version of the addressresolver for v3. You specify an implementation address, (which can be a *router* deployed by the deployer with cannon) and then it will deploy a proxy to officially connect it to the system. Supports doing the upgrades in the same call. also supports adding unmanaged contracts (ex. when we deploy to prod, using the old SNX contract) * change deployer ability to *not* deploy proxies. This should be done with cannon now * change deployer to take in `modules` argument (positional), which has the ability to specify which modules to deploy. This is used by cannon to build subsets of the module directory for the 4 different systems specified above. * add `TokenModule` and `NftModule` to `core-modules` which implements everything needed for a basic token as the title implies * remove checks for initialization modules (though not the initialization module itself), since initialization will be a much more customized process going forward and will be done by just implementing "isInitialized" for your module. * lint * add skipProxy option and remove unnecessary task name * better logging for cli mismatch errors * oops * remove unnecessary log * fix deployer * fix pkglock * fix deployer merge issues * lint fix * update pkglock * update module tests * add tests for associated systems manager and TokenModule and NftModule * lint * figured out why owner calls werent working turns out the deployment was being overwritten with same modules. to solve, deploy all systems to a new instance thanks @leo * fix from review * remove rogue file * fix cli-runner lint warnings * remove proxyContract configuration from deployments util Co-authored-by: Matías <mjlescano@protonmail.com>
- Loading branch information
Showing
52 changed files
with
17,542 additions
and
12,014 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
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
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
9 changes: 9 additions & 0 deletions
9
packages/core-modules/contracts/interfaces/IAssociatedSystemsConsumerModule.sol
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,9 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
/// @title Module for managing snxUSD token as a Satellite | ||
interface IAssociatedSystemsConsumerModule { | ||
function getToken(bytes32 id) external view returns (address); | ||
|
||
function getNft(bytes32 id) external view returns (address); | ||
} |
26 changes: 26 additions & 0 deletions
26
packages/core-modules/contracts/interfaces/IAssociatedSystemsModule.sol
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,26 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
/// @title Allows for the registration and tracking of auxillery contracts which also follow the proxy architecture | ||
interface IAssociatedSystemsModule { | ||
/// @notice create or initialize a new token | ||
function initOrUpgradeToken( | ||
bytes32 id, | ||
string memory name, | ||
string memory symbol, | ||
uint8 decimals, | ||
address impl | ||
) external; | ||
|
||
function initOrUpgradeNft( | ||
bytes32 id, | ||
string memory name, | ||
string memory symbol, | ||
string memory uri, | ||
address impl | ||
) external; | ||
|
||
function registerUnmanagedSystem(bytes32 id, address endpoint) external; | ||
|
||
function getAssociatedSystem(bytes32 id) external view returns (address proxy, bytes32 kind); | ||
} |
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,20 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "@synthetixio/core-contracts/contracts/interfaces/IERC721.sol"; | ||
|
||
/// @title NFT token identifying an Account | ||
interface INftModule is IERC721 { | ||
/// @notice returns if `initialize` has been called by the owner | ||
function isInitialized() external returns (bool); | ||
|
||
/// @notice allows owner to initialize the token after attaching a proxy | ||
function initialize( | ||
string memory tokenName, | ||
string memory tokenSymbol, | ||
string memory uri | ||
) external; | ||
|
||
/// @notice mints a new token (NFT) with the "requestedAccountId" id owned by "owner". It can ol=nly be called by the system | ||
function mint(address owner, uint requestedAccountId) external; | ||
} |
30 changes: 30 additions & 0 deletions
30
packages/core-modules/contracts/interfaces/ITokenModule.sol
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,30 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "@synthetixio/core-contracts/contracts/interfaces/IERC20.sol"; | ||
|
||
/// @title ERC20 token for snxUSD | ||
interface ITokenModule is IERC20 { | ||
/// @notice returns if `initialize` has been called by the owner | ||
function isInitialized() external returns (bool); | ||
|
||
/// @notice allows owner to initialize the token after attaching a proxy | ||
function initialize( | ||
string memory tokenName, | ||
string memory tokenSymbol, | ||
uint8 tokenDecimals | ||
) external; | ||
|
||
/// @notice mints token amount to "to" address | ||
function mint(address to, uint amount) external; | ||
|
||
/// @notice burns token amount from "to" address | ||
function burn(address to, uint amount) external; | ||
|
||
/// @notice sets token amount allowance to spender by "from" address | ||
function setAllowance( | ||
address from, | ||
address spender, | ||
uint amount | ||
) external; | ||
} |
42 changes: 42 additions & 0 deletions
42
packages/core-modules/contracts/mixins/AssociatedSystemsMixin.sol
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,42 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "@synthetixio/core-contracts/contracts/errors/InitError.sol"; | ||
import "../storage/AssociatedSystemsStorage.sol"; | ||
|
||
import "../interfaces/ITokenModule.sol"; | ||
import "../interfaces/INftModule.sol"; | ||
|
||
contract AssociatedSystemsMixin is AssociatedSystemsStorage { | ||
error MismatchAssociatedSystemKind(bytes32 expected, bytes32 actual); | ||
|
||
bytes32 internal constant _KIND_ERC20 = "erc20"; | ||
bytes32 internal constant _KIND_ERC721 = "erc721"; | ||
bytes32 internal constant _KIND_UNMANAGED = "unmanaged"; | ||
|
||
function _getToken(bytes32 id) internal view returns (ITokenModule) { | ||
_requireKind(id, _KIND_ERC20); | ||
return ITokenModule(_associatedSystemsStore().satellites[id].proxy); | ||
} | ||
|
||
function _getNft(bytes32 id) internal view returns (INftModule) { | ||
_requireKind(id, _KIND_ERC721); | ||
return INftModule(_associatedSystemsStore().satellites[id].proxy); | ||
} | ||
|
||
function _requireKind(bytes32 id, bytes32 kind) internal view { | ||
bytes32 actualKind = _associatedSystemsStore().satellites[id].kind; | ||
|
||
if (actualKind != kind && actualKind != _KIND_UNMANAGED) { | ||
revert MismatchAssociatedSystemKind(kind, actualKind); | ||
} | ||
} | ||
|
||
modifier onlyIfAssociated(bytes32 id) { | ||
if (address(_associatedSystemsStore().satellites[id].proxy) == address(0)) { | ||
revert InitError.NotInitialized(); | ||
} | ||
|
||
_; | ||
} | ||
} |
105 changes: 105 additions & 0 deletions
105
packages/core-modules/contracts/modules/AssociatedSystemsModule.sol
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,105 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "@synthetixio/core-contracts/contracts/ownership/OwnableMixin.sol"; | ||
import "@synthetixio/core-contracts/contracts/proxy/UUPSProxy.sol"; | ||
import "../interfaces/IAssociatedSystemsModule.sol"; | ||
import "../mixins/AssociatedSystemsMixin.sol"; | ||
|
||
import "@synthetixio/core-contracts/contracts/interfaces/IUUPSImplementation.sol"; | ||
import "../interfaces/IOwnerModule.sol"; | ||
import "../interfaces/ITokenModule.sol"; | ||
import "../interfaces/INftModule.sol"; | ||
|
||
contract AssociatedSystemsModule is IAssociatedSystemsModule, OwnableMixin, AssociatedSystemsMixin { | ||
function initOrUpgradeToken( | ||
bytes32 id, | ||
string memory name, | ||
string memory symbol, | ||
uint8 decimals, | ||
address impl | ||
) external override onlyOwner { | ||
AssociatedSystemsStore storage store = _associatedSystemsStore(); | ||
|
||
if (store.satellites[id].proxy != address(0)) { | ||
_requireKind(id, _KIND_ERC20); | ||
|
||
store.satellites[id].impl = impl; | ||
|
||
address proxy = store.satellites[id].proxy; | ||
|
||
// tell the associated proxy to upgrade to the new implementation | ||
IUUPSImplementation(proxy).upgradeTo(impl); | ||
|
||
_setAssociatedSystem(id, _KIND_ERC20, proxy, impl); | ||
} else { | ||
// create a new proxy and own it | ||
address proxy = address(new UUPSProxy(impl)); | ||
|
||
IOwnerModule(proxy).initializeOwnerModule(address(this)); | ||
ITokenModule(proxy).initialize(name, symbol, decimals); | ||
|
||
_setAssociatedSystem(id, _KIND_ERC20, proxy, impl); | ||
} | ||
} | ||
|
||
function initOrUpgradeNft( | ||
bytes32 id, | ||
string memory name, | ||
string memory symbol, | ||
string memory uri, | ||
address impl | ||
) external override onlyOwner { | ||
AssociatedSystemsStore storage store = _associatedSystemsStore(); | ||
|
||
if (store.satellites[id].proxy != address(0)) { | ||
_requireKind(id, _KIND_ERC721); | ||
|
||
address proxy = store.satellites[id].proxy; | ||
|
||
// tell the associated proxy to upgrade to the new implementation | ||
IUUPSImplementation(proxy).upgradeTo(impl); | ||
|
||
_setAssociatedSystem(id, _KIND_ERC721, proxy, impl); | ||
} else { | ||
// create a new proxy and own it | ||
address proxy = address(new UUPSProxy(impl)); | ||
|
||
IOwnerModule(proxy).initializeOwnerModule(address(this)); | ||
INftModule(proxy).initialize(name, symbol, uri); | ||
|
||
_setAssociatedSystem(id, _KIND_ERC721, proxy, impl); | ||
} | ||
} | ||
|
||
/** | ||
* sets a token implementation without the corresponding upgrade functionality | ||
* useful for adaptation of ex. old SNX token. The connected system does not need to be | ||
* | ||
* *NOTE:* the contract you are connecting should still be owned by your dao. The | ||
* system is not expected to be able to do upgrades for you. | ||
*/ | ||
function registerUnmanagedSystem(bytes32 id, address endpoint) external override onlyOwner { | ||
// empty string require kind will make sure the system is either unregistered or already unmanaged | ||
_requireKind(id, ""); | ||
|
||
_setAssociatedSystem(id, _KIND_UNMANAGED, endpoint, endpoint); | ||
} | ||
|
||
function _setAssociatedSystem( | ||
bytes32 id, | ||
bytes32 kind, | ||
address proxy, | ||
address impl | ||
) internal { | ||
_associatedSystemsStore().satellites[id] = AssociatedSystem(proxy, impl, kind); | ||
emit AssociatedSystemSet(kind, id, proxy, impl); | ||
} | ||
|
||
function getAssociatedSystem(bytes32 id) external view override returns (address proxy, bytes32 kind) { | ||
proxy = _associatedSystemsStore().satellites[id].proxy; | ||
kind = _associatedSystemsStore().satellites[id].kind; | ||
} | ||
|
||
event AssociatedSystemSet(bytes32 indexed kind, bytes32 indexed id, address proxy, address impl); | ||
} |
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,47 @@ | ||
//SPDX-License-Identifier: MIT | ||
pragma solidity ^0.8.0; | ||
|
||
import "@synthetixio/core-contracts/contracts/token/ERC721.sol"; | ||
import "@synthetixio/core-contracts/contracts/utils/AddressUtil.sol"; | ||
import "@synthetixio/core-contracts/contracts/initializable/InitializableMixin.sol"; | ||
import "@synthetixio/core-contracts/contracts/ownership/OwnableMixin.sol"; | ||
import "@synthetixio/core-contracts/contracts/errors/AddressError.sol"; | ||
|
||
import "../storage/NftStorage.sol"; | ||
|
||
import "../interfaces/INftModule.sol"; | ||
|
||
contract NftModule is INftModule, ERC721, NftStorage, InitializableMixin, OwnableMixin { | ||
event Mint(address owner, uint nftId); | ||
|
||
// --------------------------------------- | ||
// Chores | ||
// --------------------------------------- | ||
function _isInitialized() internal view override returns (bool) { | ||
return _nftStore().initialized; | ||
} | ||
|
||
function isInitialized() external view returns (bool) { | ||
return _isInitialized(); | ||
} | ||
|
||
function initialize( | ||
string memory tokenName, | ||
string memory tokenSymbol, | ||
string memory uri | ||
) public onlyOwner { | ||
_initialize(tokenName, tokenSymbol, uri); | ||
NftStore storage store = _nftStore(); | ||
|
||
store.initialized = true; | ||
} | ||
|
||
// --------------------------------------- | ||
// Mint/Transfer | ||
// --------------------------------------- | ||
function mint(address owner, uint256 nftId) external override onlyOwner { | ||
_mint(owner, nftId); | ||
|
||
emit Mint(owner, nftId); | ||
} | ||
} |
Oops, something went wrong.