Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Make TransparentUpgradeableProxy deploy its ProxyAdmin and optimize proxy interfaces #4382

Merged
merged 48 commits into from
Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
a4215ca
Make TransparentUpgradeableProxy deploy its own ProxyAdmin
ernestognw Jun 23, 2023
9d39cf0
Merge branch 'master' into proxy-admin-optimizations
frangio Jun 30, 2023
2acbf84
revert changes to other proxies
frangio Jun 30, 2023
e48fa5a
change transparent proxy to have upgradeTo only
frangio Jun 30, 2023
d999991
embed ProxyAdmin creation in proxy constructor
frangio Jun 30, 2023
03c2cf5
remove gas snapshot
frangio Jun 30, 2023
f570cdc
revert test changes
frangio Jun 30, 2023
0303cc7
add back upgrade
frangio Jul 1, 2023
347fac0
remove extra space
frangio Jul 6, 2023
9de9ce8
inline behavior into test file
frangio Jul 6, 2023
34381f6
remove unnecessary argument
frangio Jul 6, 2023
bff3bc7
switch proxy to upgradeToAndCall
frangio Jul 7, 2023
d9e192e
Update contracts/proxy/transparent/TransparentUpgradeableProxy.sol
ernestognw Jul 7, 2023
2dd7c05
Lint
ernestognw Jul 7, 2023
62bbd7b
Remove unused import
ernestognw Jul 7, 2023
b71fc98
Fix tests
ernestognw Jul 8, 2023
2e0c396
add else branch
frangio Jul 8, 2023
ca99577
use forceCall = false
frangio Jul 8, 2023
909fe1d
use rlp from declared dependency
frangio Jul 8, 2023
d01100a
use hardhat-network-helpers
frangio Jul 8, 2023
b425a38
hardcode nonce for address calculation
frangio Jul 8, 2023
d4f5535
remove owner argument to createProxy function
frangio Jul 8, 2023
6e48769
update docs
frangio Jul 8, 2023
0f479c6
Update create.js
Amxx Jul 8, 2023
853dc83
Update account.js
Amxx Jul 8, 2023
864be51
Update create.js
Amxx Jul 8, 2023
9349f30
Update create.js
Amxx Jul 8, 2023
cd1ac92
Update GovernorTimelockCompound.test.js
Amxx Jul 8, 2023
c4d49a4
fix lint
Amxx Jul 8, 2023
6e95dac
change proxyadmin test descriptions
frangio Jul 8, 2023
4d3bb2f
use constant string
frangio Jul 8, 2023
c37cab0
remove forceCall and upgradeTo/AndCall distinction
frangio Jul 8, 2023
5c77c03
remove unused return value from transparent proxy dispatch
frangio Jul 8, 2023
ff6a70e
lint
frangio Jul 8, 2023
223d840
remove unused import
frangio Jul 8, 2023
66a3ebf
remove unused error
frangio Jul 8, 2023
be31da2
Merge branch 'master' into proxy-admin-optimizations
frangio Jul 9, 2023
802def2
Moaaar review
ernestognw Jul 9, 2023
a22e182
don't pass empty opts to constructor removes the need for {from:...} …
Amxx Jul 9, 2023
dc040f1
Improve docs and apply suggestions
ernestognw Jul 12, 2023
4b9ec42
Improve changeset
ernestognw Jul 12, 2023
22698a6
Remove unnecessary slohint annotations
ernestognw Jul 13, 2023
60123c7
Merge branch 'master' into proxy-admin-optimizations
ernestognw Jul 13, 2023
9f18301
Add ERC1967Utils tests
ernestognw Jul 13, 2023
75ea1de
Add UpgradeableBeaconMock
ernestognw Jul 13, 2023
08ad9b5
remove unused import
frangio Jul 13, 2023
7e5c33b
Use events for checking delegatecalls
ernestognw Jul 13, 2023
703659e
Use events for checking delegatecalls
ernestognw Jul 13, 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
31 changes: 4 additions & 27 deletions contracts/proxy/transparent/ProxyAdmin.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ import {Address} from "../../utils/Address.sol";
* explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.
*/
contract ProxyAdmin is Ownable {
uint256 public immutable PROXY_ADMIN_VERSION = 2;
frangio marked this conversation as resolved.
Show resolved Hide resolved

/**
* @dev Sets the initial owner who can perform upgrades.
*/
Expand All @@ -29,32 +31,7 @@ contract ProxyAdmin is Ownable {
ITransparentUpgradeableProxy proxy,
address implementation,
bytes memory data
) public payable virtual {
// Owner checked by _upgrade
_upgrade(proxy, implementation);
Address.functionCallWithValue(address(proxy), data, msg.value);
}

/**
* @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-_dispatchUpgradeTo}.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function upgrade(ITransparentUpgradeableProxy proxy, address implementation) public virtual {
frangio marked this conversation as resolved.
Show resolved Hide resolved
// Owner checked by _upgrade
_upgrade(proxy, implementation);
}

/**
* @dev Upgrades `proxy` to `implementation`.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function _upgrade(ITransparentUpgradeableProxy proxy, address implementation) internal onlyOwner {
proxy.upgradeTo(implementation);
) public payable virtual onlyOwner {
proxy.upgradeToAndCall{ value: msg.value }(implementation, data);
}
}
14 changes: 7 additions & 7 deletions contracts/proxy/transparent/TransparentUpgradeableProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {ProxyAdmin} from "./ProxyAdmin.sol";
* include them in the ABI so this interface must be used to interact with it.
*/
interface ITransparentUpgradeableProxy is IERC1967 {
function upgradeTo(address) external payable;
function upgradeToAndCall(address, bytes calldata) external payable;
}

/**
Expand Down Expand Up @@ -90,8 +90,8 @@ contract TransparentUpgradeableProxy is ERC1967Proxy {
if (msg.sender == _admin) {
bytes memory ret;
bytes4 selector = msg.sig;
if (selector == ITransparentUpgradeableProxy.upgradeTo.selector) {
ret = _dispatchUpgradeTo();
if (selector == ITransparentUpgradeableProxy.upgradeToAndCall.selector) {
ret = _dispatchUpgradeToAndCall();
} else {
revert ProxyDeniedAdminAccess();
}
Expand All @@ -106,11 +106,11 @@ contract TransparentUpgradeableProxy is ERC1967Proxy {
/**
* @dev Upgrade the implementation of the proxy.
*/
function _dispatchUpgradeTo() private returns (bytes memory) {
_requireZeroValue();
function _dispatchUpgradeToAndCall() private returns (bytes memory) {
bool forceCall = msg.value > 0;
frangio marked this conversation as resolved.
Show resolved Hide resolved

(address newImplementation) = abi.decode(msg.data[4:], (address));
ERC1967Utils.upgradeTo(newImplementation);
(address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes));
ERC1967Utils.upgradeToAndCall(newImplementation, data, forceCall);

return "";
}
Expand Down
2 changes: 1 addition & 1 deletion contracts/proxy/utils/UUPSUpgradeable.sol
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ abstract contract UUPSUpgradeable is IERC1822Proxiable {
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal onlyOwner {}
* function _authorizeUpgrade(address) internal onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
Expand Down
2 changes: 1 addition & 1 deletion test/proxy/ERC1967/ERC1967Proxy.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ contract('ERC1967Proxy', function (accounts) {
return ERC1967Proxy.new(implementation, initData, opts);
frangio marked this conversation as resolved.
Show resolved Hide resolved
};

shouldBehaveLikeProxy(createProxy, undefined, proxyAdminOwner);
shouldBehaveLikeProxy(createProxy, proxyAdminOwner);
});
26 changes: 13 additions & 13 deletions test/proxy/Proxy.behaviour.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ const { expect } = require('chai');

const DummyImplementation = artifacts.require('DummyImplementation');

module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress, proxyCreator) {
module.exports = function shouldBehaveLikeProxy(createProxy, proxyCreator) {
it('cannot be initialized with a non-contract address', async function () {
const nonContractAddress = proxyCreator;
const initializeData = Buffer.from('');
await expectRevert.unspecified(
createProxy(nonContractAddress, proxyAdminAddress, initializeData, {
createProxy(nonContractAddress, initializeData, {
from: proxyCreator,
}),
);
Expand Down Expand Up @@ -43,7 +43,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress,
describe('when not sending balance', function () {
beforeEach('creating proxy', async function () {
this.proxy = (
await createProxy(this.implementation, proxyAdminAddress, initializeData, {
await createProxy(this.implementation, initializeData, {
from: proxyCreator,
})
).address;
Expand All @@ -57,7 +57,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress,

beforeEach('creating proxy', async function () {
this.proxy = (
await createProxy(this.implementation, proxyAdminAddress, initializeData, {
await createProxy(this.implementation, initializeData, {
from: proxyCreator,
value,
})
Expand All @@ -76,7 +76,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress,
describe('when not sending balance', function () {
beforeEach('creating proxy', async function () {
this.proxy = (
await createProxy(this.implementation, proxyAdminAddress, initializeData, {
await createProxy(this.implementation, initializeData, {
from: proxyCreator,
})
).address;
Expand All @@ -93,7 +93,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress,

it('reverts', async function () {
await expectRevert.unspecified(
createProxy(this.implementation, proxyAdminAddress, initializeData, { from: proxyCreator, value }),
createProxy(this.implementation, initializeData, { from: proxyCreator, value }),
);
});
});
Expand All @@ -106,7 +106,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress,
describe('when not sending balance', function () {
beforeEach('creating proxy', async function () {
this.proxy = (
await createProxy(this.implementation, proxyAdminAddress, initializeData, {
await createProxy(this.implementation, initializeData, {
from: proxyCreator,
})
).address;
Expand All @@ -123,7 +123,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress,

beforeEach('creating proxy', async function () {
this.proxy = (
await createProxy(this.implementation, proxyAdminAddress, initializeData, {
await createProxy(this.implementation, initializeData, {
from: proxyCreator,
value,
})
Expand All @@ -148,7 +148,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress,
describe('when not sending balance', function () {
beforeEach('creating proxy', async function () {
this.proxy = (
await createProxy(this.implementation, proxyAdminAddress, initializeData, {
await createProxy(this.implementation, initializeData, {
from: proxyCreator,
})
).address;
Expand All @@ -165,7 +165,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress,

it('reverts', async function () {
await expectRevert.unspecified(
createProxy(this.implementation, proxyAdminAddress, initializeData, { from: proxyCreator, value }),
createProxy(this.implementation, initializeData, { from: proxyCreator, value }),
);
});
});
Expand All @@ -180,7 +180,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress,
describe('when not sending balance', function () {
beforeEach('creating proxy', async function () {
this.proxy = (
await createProxy(this.implementation, proxyAdminAddress, initializeData, {
await createProxy(this.implementation, initializeData, {
from: proxyCreator,
})
).address;
Expand All @@ -197,7 +197,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress,

beforeEach('creating proxy', async function () {
this.proxy = (
await createProxy(this.implementation, proxyAdminAddress, initializeData, {
await createProxy(this.implementation, initializeData, {
from: proxyCreator,
value,
})
Expand All @@ -216,7 +216,7 @@ module.exports = function shouldBehaveLikeProxy(createProxy, proxyAdminAddress,

it('reverts', async function () {
await expectRevert(
createProxy(this.implementation, proxyAdminAddress, initializeData, { from: proxyCreator }),
createProxy(this.implementation, initializeData, { from: proxyCreator }),
'DummyImplementation reverted',
);
});
Expand Down
Loading