Skip to content
This repository has been archived by the owner on Oct 6, 2023. It is now read-only.

Closes AP-727, AP-791: EndowmentMultiSig proxy admin update & update EndowmentMultiSigFactory's registrar on new Registrar deployment #377

Merged
merged 56 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
f89f68b
Validate addresses using Validator
0xNeshi Sep 13, 2023
2a03bc4
Move events to IEndowmentMultiSigFactory
0xNeshi Sep 13, 2023
93e1ecc
Use InvalidAddress error instead of requires
0xNeshi Sep 13, 2023
c853729
Use OnlyAccountsContract error in onlyAccountsContract
0xNeshi Sep 13, 2023
2631087
Add updateRegistrar function
0xNeshi Sep 13, 2023
39a5e22
Add Initialized event
0xNeshi Sep 13, 2023
9e05fae
Add missing getInstantiationCount function to interface
0xNeshi Sep 13, 2023
056010e
Remove unused factory param in upgrade:endowmentMultiSig:emitter
0xNeshi Sep 13, 2023
b51a8f2
Add getRegistrarAddress function
0xNeshi Sep 13, 2023
add7d70
Add manage:endowmentMultiSigFactory:updateRegistrar task
0xNeshi Sep 13, 2023
138ccea
Add call to manage:endowmentMultiSigFactory:updateRegistrar to deploy…
0xNeshi Sep 13, 2023
dd8ac93
Remove unused errors from IterableMappingAddr
0xNeshi Sep 13, 2023
1bde47b
Remove unused IterableMappingAddr import from LibAccounts
0xNeshi Sep 13, 2023
de3b317
Remove endowmentIdToMultisig mapping
0xNeshi Sep 13, 2023
b30f992
Remove getInstantiationCount
0xNeshi Sep 13, 2023
e8844e6
Add endowmentMultiSigs IterableMappingAddr.Map
0xNeshi Sep 13, 2023
a2ad3cb
Add back isInstantiation function
0xNeshi Sep 13, 2023
bc8853b
Refactor constructor + remove Initialized event
0xNeshi Sep 13, 2023
66217ef
Rename register > endowmentMultiSigProxy to instantiation
0xNeshi Sep 13, 2023
a6432d4
Update comments
0xNeshi Sep 13, 2023
d246012
Implement getInstantiations function
0xNeshi Sep 13, 2023
cb5ff18
Rename getRegistrarAddress -> getRegistrar (+ add comment)
0xNeshi Sep 13, 2023
ae6a0c8
Update EndowmentMultiSig Proxies' addresses in manage:changeProxyAdmi…
0xNeshi Sep 13, 2023
870d164
Update comment for newProxyAdmin
0xNeshi Sep 13, 2023
9163786
Make proxyAdmin field internal and access through getProxyAdmin
0xNeshi Sep 13, 2023
e897e52
Rename changeProxyAdmin->changeProxyAdminForAll and fix logic
0xNeshi Sep 13, 2023
d35ed0c
Create manage:changeProxyAdmin task
0xNeshi Sep 13, 2023
285a01a
Update comment in updateRegistrar
0xNeshi Sep 13, 2023
9e3cb76
Update logging logic
0xNeshi Sep 13, 2023
b67a2d7
Refactor tasks/manage/changeProxyAdmin.ts
0xNeshi Sep 13, 2023
d0939bd
Update manage:changeProxyAdminForAll to use changeProxyAdmin task
0xNeshi Sep 13, 2023
bb537d1
Add manage:endowmentMultiSigFactory:updateProxyAdmin task
0xNeshi Sep 13, 2023
33f865a
Call manage:endowmentMultiSigFactory:updateProxyAdmin in changeProxyA…
0xNeshi Sep 13, 2023
43a8231
Update log 'Submitting Tx...' to comment
0xNeshi Sep 13, 2023
3f8b77f
Make 'to' optional, read from contract-address.json if null
0xNeshi Sep 13, 2023
1921ac9
Fix old proxyAdmin checking logic
0xNeshi Sep 13, 2023
4568c56
Target curAdmin when submitting Tx to changeProxyAdmin
0xNeshi Sep 14, 2023
cc670ee
submitMultiSigTx > owner -> msOwner
0xNeshi Sep 14, 2023
c9459a3
Remove redundant log in update reg. config
0xNeshi Sep 14, 2023
73490ce
Fix tasks/manage/changeProxyAdmin.ts
0xNeshi Sep 14, 2023
4e0f4c5
Fix tasks/manage/changeProxyAdminForAll.ts
0xNeshi Sep 14, 2023
37e8441
Add divider to changeProxyAdminForAll > changeProxiesAdmin
0xNeshi Sep 14, 2023
2da8830
Remove temp_task import
0xNeshi Sep 14, 2023
92c0cc8
Revert contract-address.json
0xNeshi Sep 14, 2023
2708898
Remove isInstantiation
0xNeshi Sep 14, 2023
73aaa90
Refactor manage:endowmentMultiSigFactory:updateProxyAdmin
0xNeshi Sep 14, 2023
f16dc42
Minor refactor manage:registrar:updateConfig
0xNeshi Sep 14, 2023
db70fba
Add comment to updateEndowmentMultiSigFactory
0xNeshi Sep 15, 2023
3853daa
Remove mention in EndowmentMultiSigFactory
0xNeshi Sep 15, 2023
ac6a68a
Revert "Remove unused errors from IterableMappingAddr"
0xNeshi Sep 15, 2023
cd97aba
Revert "Remove unused IterableMappingAddr import from LibAccounts"
0xNeshi Sep 15, 2023
ca09a49
Revert "Revert "Remove unused IterableMappingAddr import from LibAcco…
0xNeshi Sep 18, 2023
7174fd7
Revert "Revert "Remove unused errors from IterableMappingAddr""
0xNeshi Sep 18, 2023
113a36c
Add basic checkIfProxyAdmin to changeProxyAdmin
0xNeshi Sep 18, 2023
4bd7310
Move checkIfProxyAdmin to checkIfManagedByProxyAdmin
0xNeshi Sep 18, 2023
8fe4f63
Fix issues after rebase
0xNeshi Sep 19, 2023
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
1 change: 0 additions & 1 deletion contracts/core/accounts/lib/LibAccounts.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {IterableMappingAddr} from "../../../lib/IterableMappingAddr.sol";
0xNeshi marked this conversation as resolved.
Show resolved Hide resolved
import {AccountStorage} from "../storage.sol";

library LibAccounts {
Expand Down
3 changes: 0 additions & 3 deletions contracts/lib/IterableMappingAddr.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
pragma solidity ^0.8.19;

contract IterableMappingAddr {
error NonExistentKey(address key);
0xNeshi marked this conversation as resolved.
Show resolved Hide resolved
error DecrAmountExceedsValue(address key, uint256 currVal, uint256 decrVal);

struct Map {
address[] keys;
mapping(address => bool) values;
Expand Down
102 changes: 59 additions & 43 deletions contracts/multisigs/endowment-multisig/EndowmentMultiSigFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,63 +7,68 @@ import {IEndowmentMultiSigFactory} from "./interfaces/IEndowmentMultiSigFactory.
import {ProxyContract} from "../../core/proxy.sol";
import {IRegistrar} from "../../core/registrar/interfaces/IRegistrar.sol";
import {RegistrarStorage} from "../../core/registrar/storage.sol";
import {Validator} from "../../core/validator.sol";
import {IterableMappingAddr} from "../../lib/IterableMappingAddr.sol";

/// @title Multisignature wallet factory - Allows creation of multisigs wallet.
/// @author Stefan George - <[email protected]>
contract EndowmentMultiSigFactory is IEndowmentMultiSigFactory, Ownable {
/*
* Events
*/
event ContractInstantiated(address sender, address instantiation);
event ImplementationUpdated(address implementationAddress);
event ProxyAdminUpdated(address admin);

/*
* Storage
*/
mapping(address => bool) public isInstantiation;
mapping(address => address[]) public instantiations;
mapping(uint256 => address) public endowmentIdToMultisig;
contract EndowmentMultiSigFactory is IEndowmentMultiSigFactory, Ownable, IterableMappingAddr {
0xNeshi marked this conversation as resolved.
Show resolved Hide resolved
/*////////////////////////////////////////////////
STORAGE
*/ ///////////////////////////////////////////////
IterableMappingAddr.Map endowmentMultiSigs;

address public implementationAddress;
address public proxyAdmin;
address proxyAdmin;
IRegistrar registrar;
0xNeshi marked this conversation as resolved.
Show resolved Hide resolved

constructor(address _implementationAddress, address _proxyAdmin, address _registrar) {
require(_implementationAddress != address(0), "Invalid Address");
require(_proxyAdmin != address(0), "Invalid Address");
require(_registrar != address(0), "Invalid Address");

registrar = IRegistrar(_registrar);
implementationAddress = _implementationAddress;
emit ImplementationUpdated(_implementationAddress);

proxyAdmin = _proxyAdmin;
emit ProxyAdminUpdated(_proxyAdmin);
constructor(address _implementationAddress, address _proxyAdmin, address registrarAddress) {
updateImplementation(_implementationAddress);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Constructor behavior was the same as if these functions were called one-by-one

updateProxyAdmin(_proxyAdmin);
updateRegistrar(registrarAddress);
}

/*////////////////////////////////////////////////
MODIFIERS
*/ ///////////////////////////////////////////////

modifier onlyAccountsContract() {
RegistrarStorage.Config memory registrarConfig = registrar.queryConfig();
require(msg.sender == registrarConfig.accountsContract, "Only Accounts Contract");
if (msg.sender != registrarConfig.accountsContract) {
revert OnlyAccountsContract();
}
_;
}

/*
* Public functions
*/
/// @dev Returns number of instantiations by creator.
/// @param creator Contract creator.
/// @return Returns number of instantiations by creator.
function getInstantiationCount(address creator) public view returns (uint256) {
return instantiations[creator].length;
/*////////////////////////////////////////////////
IMPLEMENTATION
*/ ///////////////////////////////////////////////

/// @notice Get all EndowmentMultiSig proxy contract instantiations.
/// @return Array of instantiation addresses.
function getInstantiations() external view returns (address[] memory) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need this to be able to update all of the instantiations' proxy admins

return endowmentMultiSigs.keys;
}

/// @notice Get stored registrar address.
/// @return address of the stored registrar.
function getRegistrar() external view returns (address) {
0xNeshi marked this conversation as resolved.
Show resolved Hide resolved
return address(registrar);
}

/// @notice Get proxy admin address.
/// @return address of the proxy admin.
function getProxyAdmin() external view returns (address) {
return proxyAdmin;
}

/**
* @dev Updates the implementation address
* @param _implementationAddress The address of the new implementation
*/
function updateImplementation(address _implementationAddress) public onlyOwner {
require(_implementationAddress != address(0), "Invalid Address");
if (!Validator.addressChecker(_implementationAddress)) {
revert InvalidAddress("_implementationAddress");
}
implementationAddress = _implementationAddress;
emit ImplementationUpdated(_implementationAddress);
}
Expand All @@ -73,11 +78,25 @@ contract EndowmentMultiSigFactory is IEndowmentMultiSigFactory, Ownable {
* @param _proxyAdmin The address of the new proxy admin
*/
function updateProxyAdmin(address _proxyAdmin) public onlyOwner {
require(_proxyAdmin != address(0), "Invalid Address");
if (!Validator.addressChecker(_proxyAdmin)) {
revert InvalidAddress("_proxyAdmin");
}
proxyAdmin = _proxyAdmin;
emit ProxyAdminUpdated(_proxyAdmin);
}

/**
* @dev Updates the registrar address
* @param registrarAddress The address of the new registrar
*/
function updateRegistrar(address registrarAddress) public onlyOwner {
if (!Validator.addressChecker(registrarAddress)) {
revert InvalidAddress("registrarAddress");
}
registrar = IRegistrar(registrarAddress);
emit RegistrarUpdated(registrarAddress);
}

/** @dev Create a new multisig wallet for an endowment
* @param endowmentId the endowment id
* @param emitterAddress the emitter of the multisig
Expand Down Expand Up @@ -113,18 +132,15 @@ contract EndowmentMultiSigFactory is IEndowmentMultiSigFactory, Ownable {
);

register(wallet);
// also store address of multisig in endowmentIdToMultisig
endowmentIdToMultisig[endowmentId] = wallet;
}

/*
* Internal functions
*/
/// @dev Registers contract in factory registry.
/// @param instantiation Address of contract instantiation.
/// @param instantiation Address of EndowmentMultiSig proxy contract instantiation.
function register(address instantiation) internal {
isInstantiation[instantiation] = true;
instantiations[msg.sender].push(instantiation);
IterableMappingAddr.set(endowmentMultiSigs, instantiation, true);
emit ContractInstantiated(msg.sender, instantiation);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,23 @@
pragma solidity ^0.8.19;

interface IEndowmentMultiSigFactory {
/*////////////////////////////////////////////////
EVENTS
*/ ///////////////////////////////////////////////
event ContractInstantiated(address sender, address instantiation);
event ImplementationUpdated(address implementationAddress);
event ProxyAdminUpdated(address admin);
event RegistrarUpdated(address registrar);

/*////////////////////////////////////////////////
ERRORS
*/ ///////////////////////////////////////////////
error InvalidAddress(string param);
error OnlyAccountsContract();

/*////////////////////////////////////////////////
EXTERNAL FUNCTIONS
*/ ////////////////////////////////////////////////
function create(
uint256 endowmentId,
address emitterAddress,
Expand All @@ -14,5 +31,17 @@ interface IEndowmentMultiSigFactory {

function updateProxyAdmin(address proxyAdminAddress) external;

function endowmentIdToMultisig(uint256 endowmentId) external returns (address);
function updateRegistrar(address registrarAddress) external;

/// @notice Get all EndowmentMultiSig proxy contract instantiations.
/// @return Array of instantiation addresses.
function getInstantiations() external view returns (address[] memory);

/// @notice Get stored registrar address.
/// @return address of the stored registrar.
function getRegistrar() external view returns (address);

/// @notice Get proxy admin address.
/// @return address of the proxy admin.
function getProxyAdmin() external view returns (address);
}
5 changes: 5 additions & 0 deletions tasks/deploy/deployRegistrar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ task(
apTeamSignerPkey: taskArgs.apTeamSignerPkey,
yes: true,
});
await hre.run("manage:endowmentMultiSigFactory:updateRegistrar", {
registrar: registrar.proxy.contract.address,
apTeamSignerPkey: taskArgs.apTeamSignerPkey,
yes: true,
});

if (!isLocalNetwork(hre) && !taskArgs.skipVerify) {
await verify(hre, registrar.implementation);
Expand Down
6 changes: 3 additions & 3 deletions tasks/helpers/submitMultiSigTx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ import {filterEvents, logger} from "utils";
/**
* Submits a transaction to the designated Multisig contract and executes it if possible.
* @param msAddress address of the Multisig contract
* @param owner signer representing one of the Multisig owners
* @param msOwner signer representing one of the Multisig owners
* @param destination transaction target address
* @param data transaction data payload
* @returns boolean value indicating whether the transaction was executed or not (i.e. is pending confirmation by other owners)
*/
export async function submitMultiSigTx(
msAddress: string,
owner: Signer,
msOwner: Signer,
destination: string,
data: BytesLike
): Promise<boolean> {
logger.out(`Submitting transaction to Multisig at address: ${msAddress}...`);
const multisig = IMultiSigGeneric__factory.connect(msAddress, owner);
const multisig = IMultiSigGeneric__factory.connect(msAddress, msOwner);
const feeData = await multisig.provider.getFeeData();
const tx = await multisig.submitTransaction(destination, 0, data, "0x", {
gasPrice: feeData.gasPrice ?? undefined,
Expand Down
Loading