-
Notifications
You must be signed in to change notification settings - Fork 270
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Ignore UPGRADE_INTERFACE_VERSION if selector returns anything other t…
…han "5.0.0" (#926) Co-authored-by: Ernesto García <[email protected]>
- Loading branch information
1 parent
6104d96
commit 173759d
Showing
11 changed files
with
343 additions
and
17 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
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
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
23 changes: 23 additions & 0 deletions
23
packages/plugin-hardhat/contracts/GreeterProxiable40Fallback.sol
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,23 @@ | ||
pragma solidity >= 0.6.0 <0.8.0; | ||
|
||
import { Proxiable } from "./utils/Proxiable.sol"; | ||
|
||
contract GreeterProxiable40Fallback is Proxiable { | ||
string greeting; | ||
|
||
function initialize(string memory _greeting) public { | ||
greeting = _greeting; | ||
} | ||
|
||
function greet() public view returns (string memory) { | ||
return greeting; | ||
} | ||
|
||
fallback() external {} | ||
} | ||
|
||
contract GreeterProxiable40FallbackV2 is GreeterProxiable40Fallback { | ||
function resetGreeting() public { | ||
greeting = "Hello World"; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
packages/plugin-hardhat/contracts/GreeterProxiable40FallbackString.sol
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,25 @@ | ||
pragma solidity >= 0.6.0 <0.8.0; | ||
|
||
import { Proxiable } from "./utils/Proxiable.sol"; | ||
|
||
contract GreeterProxiable40FallbackString is Proxiable { | ||
string greeting; | ||
|
||
function initialize(string memory _greeting) public { | ||
greeting = _greeting; | ||
} | ||
|
||
function greet() public view returns (string memory) { | ||
return greeting; | ||
} | ||
|
||
fallback(bytes calldata) external returns (bytes memory) { | ||
return abi.encode(greeting); | ||
} | ||
} | ||
|
||
contract GreeterProxiable40FallbackStringV2 is GreeterProxiable40FallbackString { | ||
function resetGreeting() public { | ||
greeting = "Hello World"; | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
packages/plugin-hardhat/contracts/GreeterTransparent40Fallback.sol
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,44 @@ | ||
pragma solidity >= 0.6.0 <0.8.0; | ||
|
||
// These contracts are for testing only, they are not safe for use in production. | ||
|
||
interface ITransparentUpgradeableProxy { | ||
function upgradeTo(address) external; | ||
function upgradeToAndCall(address, bytes memory) external payable; | ||
} | ||
|
||
contract UnsafeAdminFallback { | ||
// NOT SAFE FOR PRODUCTION USE. ANYONE CAN UPGRADE THE PROXY THROUGH THE BELOW. | ||
|
||
function upgrade(ITransparentUpgradeableProxy proxy, address implementation) public virtual { | ||
proxy.upgradeTo(implementation); | ||
} | ||
|
||
function upgradeAndCall( | ||
ITransparentUpgradeableProxy proxy, | ||
address implementation, | ||
bytes memory data | ||
) public payable virtual { | ||
proxy.upgradeToAndCall{value: msg.value}(implementation, data); | ||
} | ||
|
||
fallback() external {} | ||
} | ||
|
||
contract GreeterTransparent40Fallback { | ||
string greeting; | ||
|
||
function initialize(string memory _greeting) public { | ||
greeting = _greeting; | ||
} | ||
|
||
function greet() public view returns (string memory) { | ||
return greeting; | ||
} | ||
} | ||
|
||
contract GreeterTransparent40FallbackV2 is GreeterTransparent40Fallback { | ||
function resetGreeting() public { | ||
greeting = "Hello World"; | ||
} | ||
} |
46 changes: 46 additions & 0 deletions
46
packages/plugin-hardhat/contracts/GreeterTransparent40FallbackString.sol
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 @@ | ||
pragma solidity >= 0.6.0 <0.8.0; | ||
|
||
// These contracts are for testing only, they are not safe for use in production. | ||
|
||
interface ITransparentUpgradeableProxy { | ||
function upgradeTo(address) external; | ||
function upgradeToAndCall(address, bytes memory) external payable; | ||
} | ||
|
||
contract UnsafeAdminFallbackString { | ||
// NOT SAFE FOR PRODUCTION USE | ||
|
||
function upgrade(ITransparentUpgradeableProxy proxy, address implementation) public virtual { | ||
proxy.upgradeTo(implementation); | ||
} | ||
|
||
function upgradeAndCall( | ||
ITransparentUpgradeableProxy proxy, | ||
address implementation, | ||
bytes memory data | ||
) public payable virtual { | ||
proxy.upgradeToAndCall{value: msg.value}(implementation, data); | ||
} | ||
|
||
fallback(bytes calldata) external returns (bytes memory) { | ||
return abi.encode("foo"); | ||
} | ||
} | ||
|
||
contract GreeterTransparent40FallbackString { | ||
string greeting; | ||
|
||
function initialize(string memory _greeting) public { | ||
greeting = _greeting; | ||
} | ||
|
||
function greet() public view returns (string memory) { | ||
return greeting; | ||
} | ||
} | ||
|
||
contract GreeterTransparent40FallbackStringV2 is GreeterTransparent40FallbackString { | ||
function resetGreeting() public { | ||
greeting = "Hello World"; | ||
} | ||
} |
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
104 changes: 104 additions & 0 deletions
104
packages/plugin-hardhat/test/transparent-admin-unknown-upgrade-interface.js
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,104 @@ | ||
const test = require('ava'); | ||
const sinon = require('sinon'); | ||
|
||
const { ethers, upgrades } = require('hardhat'); | ||
const hre = require('hardhat'); | ||
|
||
const TransparentUpgradableProxy = require('@openzeppelin/upgrades-core/artifacts/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json'); | ||
|
||
test.before(async t => { | ||
t.context.GreeterTransparent40Fallback = await ethers.getContractFactory('GreeterTransparent40Fallback'); | ||
t.context.GreeterTransparent40FallbackV2 = await ethers.getContractFactory('GreeterTransparent40FallbackV2'); | ||
t.context.UnsafeAdminFallback = await ethers.getContractFactory('UnsafeAdminFallback'); | ||
|
||
t.context.GreeterTransparent40FallbackString = await ethers.getContractFactory('GreeterTransparent40FallbackString'); | ||
t.context.GreeterTransparent40FallbackStringV2 = await ethers.getContractFactory( | ||
'GreeterTransparent40FallbackStringV2', | ||
); | ||
t.context.UnsafeAdminFallbackString = await ethers.getContractFactory('UnsafeAdminFallbackString'); | ||
|
||
t.context.TransparentUpgradableProxy = await ethers.getContractFactory( | ||
TransparentUpgradableProxy.abi, | ||
TransparentUpgradableProxy.bytecode, | ||
); | ||
}); | ||
|
||
function getInitializerData(contractInterface, args) { | ||
return contractInterface.encodeFunctionData('initialize', args); | ||
} | ||
|
||
test('admin with unknown upgrades interface version due to fallback returning non-string', async t => { | ||
const { | ||
GreeterTransparent40Fallback, | ||
GreeterTransparent40FallbackV2, | ||
UnsafeAdminFallback, | ||
TransparentUpgradableProxy, | ||
} = t.context; | ||
|
||
const impl = await GreeterTransparent40Fallback.deploy(); | ||
await impl.waitForDeployment(); | ||
const admin = await UnsafeAdminFallback.deploy(); | ||
await admin.waitForDeployment(); | ||
const proxy = await TransparentUpgradableProxy.deploy( | ||
await impl.getAddress(), | ||
await admin.getAddress(), | ||
getInitializerData(GreeterTransparent40Fallback.interface, ['Hello, Hardhat!']), | ||
); | ||
await proxy.waitForDeployment(); | ||
|
||
const greeter = GreeterTransparent40Fallback.attach(await proxy.getAddress()); | ||
t.is(await greeter.greet(), 'Hello, Hardhat!'); | ||
|
||
await upgrades.forceImport(await proxy.getAddress(), GreeterTransparent40Fallback); | ||
|
||
const debugStub = sinon.stub(); | ||
const upgradeProxy = require('../dist/upgrade-proxy').makeUpgradeProxy(hre, false, debugStub); | ||
|
||
const greeter2 = await upgradeProxy(proxy, GreeterTransparent40FallbackV2); | ||
await greeter2.resetGreeting(); | ||
t.is(await greeter2.greet(), 'Hello World'); | ||
|
||
t.true( | ||
debugStub.calledWith( | ||
`Unexpected type for UPGRADE_INTERFACE_VERSION at address ${await admin.getAddress()}. Expected a string`, | ||
), | ||
); | ||
}); | ||
|
||
test('admin with unknown upgrades interface version due to fallback returning string', async t => { | ||
const { | ||
GreeterTransparent40FallbackString, | ||
GreeterTransparent40FallbackStringV2, | ||
UnsafeAdminFallbackString, | ||
TransparentUpgradableProxy, | ||
} = t.context; | ||
|
||
const impl = await GreeterTransparent40FallbackString.deploy(); | ||
await impl.waitForDeployment(); | ||
const admin = await UnsafeAdminFallbackString.deploy(); | ||
await admin.waitForDeployment(); | ||
const proxy = await TransparentUpgradableProxy.deploy( | ||
await impl.getAddress(), | ||
await admin.getAddress(), | ||
getInitializerData(GreeterTransparent40FallbackString.interface, ['Hello, Hardhat!']), | ||
); | ||
await proxy.waitForDeployment(); | ||
|
||
const greeter = GreeterTransparent40FallbackString.attach(await proxy.getAddress()); | ||
t.is(await greeter.greet(), 'Hello, Hardhat!'); | ||
|
||
await upgrades.forceImport(await proxy.getAddress(), GreeterTransparent40FallbackString); | ||
|
||
const debugStub = sinon.stub(); | ||
const upgradeProxy = require('../dist/upgrade-proxy').makeUpgradeProxy(hre, false, debugStub); | ||
|
||
const greeter2 = await upgradeProxy(proxy, GreeterTransparent40FallbackStringV2); | ||
await greeter2.resetGreeting(); | ||
t.is(await greeter2.greet(), 'Hello World'); | ||
|
||
t.true( | ||
debugStub.calledWith( | ||
`Unknown UPGRADE_INTERFACE_VERSION foo for proxy admin at ${await admin.getAddress()}. Expected 5.0.0`, | ||
), | ||
); | ||
}); |
Oops, something went wrong.