Contract that manages deployment and upgrades of delegatecall proxies. An implementation identifier can be created on the proxy manager which is used to specify the logic address for a particular contract type, and to upgrade the implementation as needed.
A one-to-one proxy is a single proxy contract with an upgradeable implementation address.
A many-to-one proxy is a single upgradeable implementation address that may be used by many proxy contracts.
The proxy manager has a single address as its owner. The owner is the sole account with the following permissions:
- Create new many-to-one implementations
- Create new one-to-one proxies
- Modify the implementation address of existing proxies
- Lock proxies
- Designate approved deployers
- Remove approved deployers
- Modify the owner address
Approved deployers may only deploy many-to-one proxies.
Proxies can be upgraded by the owner if they are not locked. Many-to-one proxy implementations are upgraded by calling the holder contract for the implementation ID being upgraded. One-to-one proxies are upgraded by calling the proxy contract directly. The owner can lock a one-to-one proxy or many-to-one implementation ID so that it becomes impossible to upgrade.
- Access Controls
- Implementation Management
createManyToOneProxyRelationship(bytes32 implementationID, address implementation)
lockImplementationManyToOne(bytes32 implementationID)
lockImplementationOneToOne(address proxyAddress)
setImplementationAddressManyToOne(bytes32 implementationID, address implementation)
setImplementationAddressOneToOne(address proxyAddress, address implementation)
- Proxy Deployment
- Queries
isImplementationLocked(bytes32 implementationID)
isImplementationLocked(address proxyAddress)
isApprovedDeployer(address deployer)
getImplementationHolder()
getImplementationHolder(bytes32 implementationID)
computeProxyAddressOneToOne(address originator, bytes32 suppliedSalt)
computeProxyAddressManyToOne(address originator, bytes32 implementationID, bytes32 suppliedSalt)
computeHolderAddressManyToOne(bytes32 implementationID)
- Internal Functions
function approveDeployer(address deployer)
Allows deployer
to deploy many-to-one proxies.
function revokeDeployerApproval(address deployer)
Prevents deployer
from deploying many-to-one proxies.
function createManyToOneProxyRelationship(bytes32 implementationID, address implementation)
Creates a many-to-one proxy relationship. Deploys an implementation holder contract which stores the implementation address for many proxies. The implementation address can be updated on the holder to change the runtime code used by all its proxies.
-
implementationID
: ID for the implementation, used to identify the proxies that use it. Also used as the salt in the create2 call when deploying the implementation holder contract. -
implementation
: Address with the runtime code the proxies should use.
function lockImplementationManyToOne(bytes32 implementationID)
Lock the current implementation for proxyAddress
so that it can never be upgraded again.
function lockImplementationOneToOne(address proxyAddress)
Lock the current implementation for proxyAddress
so that it can never be upgraded again.
function setImplementationAddressManyToOne(bytes32 implementationID, address implementation)
Updates the implementation address for a many-to-one proxy relationship.
-
implementationID
: Identifier for the implementation. -
implementation
: Address with the runtime code the proxies should use.
function setImplementationAddressOneToOne(address proxyAddress, address implementation)
Updates the implementation address for a one-to-one proxy. Note: This could work for many-to-one as well if the caller provides the implementation holder address in place of the proxy address, as they use the same access control and update mechanism.
-
proxyAddress
: Address of the deployed proxy -
implementation
: Address with the runtime code for the proxy to use.
function deployProxyOneToOne(bytes32 suppliedSalt, address implementation) returns (address proxyAddress)
Deploy a proxy contract with a one-to-one relationship with its implementation. The proxy will have its own implementation address which can be updated by the proxy manager.
-
suppliedSalt
: Salt provided by the account requesting deployment. -
implementation
: Address of the contract with the runtime code that the proxy should use.
function deployProxyManyToOne(bytes32 implementationID, bytes32 suppliedSalt) returns (address proxyAddress)
Deploy a proxy with a many-to-one relationship with its implemenation. The proxy will call the implementation holder for every transaction to determine the address to use in calls.
-
implementationID
: Identifier for the proxy's implementation. -
suppliedSalt
: Salt provided by the account requesting deployment.
function isImplementationLocked(bytes32 implementationID) returns (bool)
Returns a boolean stating whether implementationID
is locked.
function isImplementationLocked(address proxyAddress) returns (bool)
Returns a boolean stating whether proxyAddress
is locked.
function isApprovedDeployer(address deployer) returns (bool)
Returns a boolean stating whether deployer
is allowed to deploy many-to-one
proxies.
function getImplementationHolder() returns (address)
Queries the temporary storage value _implementationHolder
.
This is used in the constructor of the many-to-one proxy contract
so that the create2 address is static (adding constructor arguments
would change the codehash) and the implementation holder can be
stored as a constant.
function getImplementationHolder(bytes32 implementationID) returns (address)
Returns the address of the implementation holder contract
for implementationID
.
function computeProxyAddressOneToOne(address originator, bytes32 suppliedSalt) returns (address)
Computes the create2 address for a one-to-one proxy requested
by originator
using suppliedSalt
.
-
originator
: Address of the account requesting deployment. -
suppliedSalt
: Salt provided by the account requesting deployment.
function computeProxyAddressManyToOne(address originator, bytes32 implementationID, bytes32 suppliedSalt) returns (address)
Computes the create2 address for a many-to-one proxy for the
implementation implementationID
requested by originator
using
suppliedSalt
.
-
originator
: Address of the account requesting deployment. -
implementationID
: The identifier for the contract implementation. -
suppliedSalt
: Salt provided by the account requesting deployment.
function computeHolderAddressManyToOne(bytes32 implementationID) returns (address)
Computes the create2 address of the implementation holder
for implementationID
.
implementationID
: The identifier for the contract implementation.
function _setImplementation(address proxyOrHolder, address implementation)
Sets the implementation address for a one-to-one proxy or many-to-one implementation holder. Both use the same access control and update mechanism, which is the receipt of a call from the proxy manager with the abi-encoded implementation address as the only calldata. Note: Verifies that the implementation address is a contract.
-
proxyOrHolder
: Address of the one-to-one proxy or many-to-one implementation holder contract. -
implementation
: Address of the contract with the runtime code that the proxy or proxies should use.