Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Prev Previous commit
Next Next commit
Apply suggestions
Co-authored-by: Francisco <[email protected]>
  • Loading branch information
ernestognw and frangio committed Jun 15, 2023
commit 4af8379d6937ab6929b554908b5e547281ed8542
2 changes: 1 addition & 1 deletion .changeset/happy-falcons-walk.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
'openzeppelin-solidity': major
---

`TransparentUpgradeableProxy`: Added an immutable admin set during construction to avoid unnecessary storage reads on every proxy call, and removed the ability to change the admin from both proxy and `ProxyAdmin`
`TransparentUpgradeableProxy`: Added an immutable admin set during construction to avoid unnecessary storage reads on every proxy call, and removed the ability to change the admin from both proxy and `ProxyAdmin`.
7 changes: 4 additions & 3 deletions contracts/proxy/transparent/TransparentUpgradeableProxy.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ interface ITransparentUpgradeableProxy is IERC1967 {
* implementation. If the admin tries to call a function on the implementation it will fail with an error that says
* "admin cannot fallback to proxy target".
*
* These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing
* the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due
* to sudden errors when trying to call a function from the proxy implementation.
* These properties mean that the admin account can only be used for upgrading the proxy, so it's best if it's a dedicated
* account that is not used for anything else. This will avoid headaches due to sudden errors when trying to call a function
* from the proxy implementation.
*
* Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
* you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.
Expand Down Expand Up @@ -75,6 +75,7 @@ contract TransparentUpgradeableProxy is ERC1967Proxy {
*/
constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {
_admin = admin_;
// Set the storage value and emit an event for ERC-1967 compatibility
ERC1967Utils.changeAdmin(admin_);
}

Expand Down
14 changes: 12 additions & 2 deletions test/proxy/transparent/TransparentUpgradeableProxy.behaviour.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,18 @@ module.exports = function shouldBehaveLikeTransparentUpgradeableProxy(createProx
});
});

describe('proxyAdmin', function () {
it('sets the admin in the storage ', async function () {
describe('proxy admin', function () {
it('emits AdminChanged event during construction', async function () {
const proxy = await createProxy(this.implementationV0, proxyAdminAddress, Buffer.from(''), {
from: proxyAdminOwner,
});
expectEvent.inConstruction(proxy, 'AdminChanged', {
previousAdmin: ZERO_ADDRESS,
newAdmin: proxyAdminAddress,
});
});

it('sets the admin in the storage and emits AdminChanged', async function () {
expect(await getAddressInSlot(this.proxy, AdminSlot)).to.be.equal(proxyAdminAddress);
});

Expand Down