-
Notifications
You must be signed in to change notification settings - Fork 15
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
1 parent
d564a9f
commit 5926e9b
Showing
5 changed files
with
331 additions
and
11 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
# pragma version 0.3.10 | ||
# pragma evm-version paris | ||
""" | ||
@title ProxyAdmin | ||
@notice Thin proxy allowing shared ownership of contracts | ||
@author Ben Hauser | ||
@license MIT | ||
""" | ||
|
||
|
||
event TransactionExecuted: | ||
admin: indexed(address) | ||
target: indexed(address) | ||
calldata: Bytes[100000] | ||
value: uint256 | ||
|
||
event RequestAdminChange: | ||
current_admin: address | ||
future_admin: address | ||
|
||
event RevokeAdminChange: | ||
current_admin: address | ||
future_admin: address | ||
calling_admin: address | ||
|
||
event ApproveAdminChange: | ||
current_admin: address | ||
future_admin: address | ||
calling_admin: address | ||
|
||
event AcceptAdminChange: | ||
previous_admin: address | ||
current_admin: address | ||
|
||
|
||
admins: public(address[2]) | ||
|
||
pending_current_admin: uint256 | ||
pending_new_admin: address | ||
change_approved: bool | ||
|
||
|
||
@external | ||
def __init__(_authorized: address[2]): | ||
""" | ||
@notice Contract constructor | ||
@param _authorized Admin accounts for this contract | ||
""" | ||
self.admins = _authorized | ||
|
||
|
||
@payable | ||
@external | ||
def execute(_target: address, _calldata: Bytes[100000]): | ||
""" | ||
@notice Execute a contract call | ||
@dev Ether sent when calling this function is forwarded onward | ||
@param _target Address of the contract to call | ||
@param _calldata Calldata to use in the call | ||
""" | ||
assert msg.sender in self.admins # dev: only admin | ||
|
||
raw_call(_target, _calldata, value=msg.value) | ||
log TransactionExecuted(msg.sender, _target, _calldata, msg.value) | ||
|
||
|
||
@view | ||
@external | ||
def get_admin_change_status() -> (address, address, bool): | ||
""" | ||
@notice Get information about a pending admin change | ||
@return Admin address to be replaced, | ||
admin address to be added, | ||
has change been approved? | ||
""" | ||
idx: uint256 = self.pending_current_admin | ||
if idx == 0: | ||
return ZERO_ADDRESS, ZERO_ADDRESS, False | ||
else: | ||
return self.admins[idx - 1], self.pending_new_admin, self.change_approved | ||
|
||
|
||
@external | ||
def request_admin_change(_new_admin: address): | ||
""" | ||
@notice Initiate changing an admin address | ||
@param _new_admin New admin address (replaces msg.sender) | ||
""" | ||
assert self.pending_current_admin == 0 # dev: already an active request | ||
|
||
admin_list: address[2] = self.admins | ||
assert _new_admin not in admin_list # dev: new admin is already admin | ||
|
||
for i in range(2): | ||
if admin_list[i] == msg.sender: | ||
self.pending_current_admin = i + 1 | ||
self.pending_new_admin = _new_admin | ||
log RequestAdminChange(msg.sender, _new_admin) | ||
return | ||
|
||
raise # dev: only admin | ||
|
||
|
||
@external | ||
def approve_admin_change(): | ||
""" | ||
@notice Approve changing an admin address | ||
@dev Only callable by the 2nd admin address (the one that will not change) | ||
""" | ||
idx: uint256 = self.pending_current_admin | ||
|
||
assert idx > 0 # dev: no active request | ||
assert msg.sender == self.admins[idx % 2] # dev: caller is not 2nd admin | ||
|
||
self.change_approved = True | ||
log ApproveAdminChange(self.admins[idx - 1], self.pending_new_admin, msg.sender) | ||
|
||
|
||
@external | ||
def revoke_admin_change(): | ||
""" | ||
@notice Revoke changing an admin address | ||
@dev May be called by either admin at any time to reset the process, | ||
even if approval has previous been given | ||
""" | ||
assert msg.sender in self.admins # dev: only admin | ||
|
||
idx: uint256 = self.pending_current_admin | ||
pending_admin: address = ZERO_ADDRESS | ||
if idx > 0: | ||
pending_admin = self.admins[idx - 1] | ||
|
||
log RevokeAdminChange(pending_admin, self.pending_new_admin, msg.sender) | ||
|
||
self.pending_current_admin = 0 | ||
self.pending_new_admin = ZERO_ADDRESS | ||
self.change_approved = False | ||
|
||
|
||
|
||
@external | ||
def accept_admin_change(): | ||
""" | ||
@notice Accept a changed admin address | ||
@dev Only callable by the new admin address, after approval has been given | ||
""" | ||
assert self.change_approved == True # dev: change not approved | ||
assert msg.sender == self.pending_new_admin # dev: only new admin | ||
|
||
idx: uint256 = self.pending_current_admin - 1 | ||
log AcceptAdminChange(self.admins[idx], msg.sender) | ||
self.admins[idx] = msg.sender | ||
|
||
self.pending_current_admin = 0 | ||
self.pending_new_admin = ZERO_ADDRESS | ||
self.change_approved = False |
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,46 @@ | ||
import os | ||
import sys | ||
|
||
import boa | ||
import deployment_utils as deploy_utils | ||
from boa.network import NetworkEnv | ||
from deploy_infra import set_evm_version | ||
from eth_abi import encode | ||
from eth_account import Account | ||
from rich.console import Console as RichConsole | ||
|
||
logger = RichConsole(file=sys.stdout) | ||
|
||
|
||
def deploy_proxy_admin(network, url, account, fork=False): | ||
|
||
logger.log(f"Deploying ProxyAdmin for {network} ...") | ||
|
||
if fork: | ||
boa.env.fork(url) | ||
logger.log("Forkmode ...") | ||
else: | ||
logger.log("Prodmode ...") | ||
boa.set_env(NetworkEnv(url)) | ||
boa.env.add_account(Account.from_key(os.environ[account])) | ||
|
||
# deploy thin proxy if no owners exist: | ||
proxy_admin_contract_obj = set_evm_version("./contracts/ProxyAdmin.vy", network) | ||
args = [deploy_utils.FIDDYDEPLOYER, deploy_utils.BABE] | ||
encoded_args = encode(["address", "address"], args).hex() | ||
logger.log(f"Constructor: {encoded_args}") | ||
proxy_admin = proxy_admin_contract_obj.deploy(args) | ||
logger.log(f"Deployed ProxyAdmin at {proxy_admin.address} on {network}.") | ||
|
||
|
||
def main(): | ||
deploy_proxy_admin( | ||
"aurora:mainnet", | ||
os.environ["RPC_AURORA"], | ||
"FIDDYDEPLOYER", | ||
fork=False, | ||
) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
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.