ProxyAdmin.test.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. const { accounts, contract } = require('@openzeppelin/test-environment');
  2. const { expectRevert } = require('@openzeppelin/test-helpers');
  3. const { expect } = require('chai');
  4. const ImplV1 = contract.fromArtifact('DummyImplementation');
  5. const ImplV2 = contract.fromArtifact('DummyImplementationV2');
  6. const ProxyAdmin = contract.fromArtifact('ProxyAdmin');
  7. const TransparentUpgradeableProxy = contract.fromArtifact('TransparentUpgradeableProxy');
  8. describe('ProxyAdmin', function () {
  9. const [proxyAdminOwner, newAdmin, anotherAccount] = accounts;
  10. before('set implementations', async function () {
  11. this.implementationV1 = await ImplV1.new();
  12. this.implementationV2 = await ImplV2.new();
  13. });
  14. beforeEach(async function () {
  15. const initializeData = Buffer.from('');
  16. this.proxyAdmin = await ProxyAdmin.new({ from: proxyAdminOwner });
  17. this.proxy = await TransparentUpgradeableProxy.new(
  18. this.implementationV1.address,
  19. this.proxyAdmin.address,
  20. initializeData,
  21. { from: proxyAdminOwner },
  22. );
  23. });
  24. it('has an owner', async function () {
  25. expect(await this.proxyAdmin.owner()).to.equal(proxyAdminOwner);
  26. });
  27. describe('#getProxyAdmin', function () {
  28. it('returns proxyAdmin as admin of the proxy', async function () {
  29. const admin = await this.proxyAdmin.getProxyAdmin(this.proxy.address);
  30. expect(admin).to.be.equal(this.proxyAdmin.address);
  31. });
  32. });
  33. describe('#changeProxyAdmin', function () {
  34. it('fails to change proxy admin if its not the proxy owner', async function () {
  35. await expectRevert(
  36. this.proxyAdmin.changeProxyAdmin(this.proxy.address, newAdmin, { from: anotherAccount }),
  37. 'caller is not the owner',
  38. );
  39. });
  40. it('changes proxy admin', async function () {
  41. await this.proxyAdmin.changeProxyAdmin(this.proxy.address, newAdmin, { from: proxyAdminOwner });
  42. expect(await this.proxy.admin.call({ from: newAdmin })).to.eq(newAdmin);
  43. });
  44. });
  45. describe('#getProxyImplementation', function () {
  46. it('returns proxy implementation address', async function () {
  47. const implementationAddress = await this.proxyAdmin.getProxyImplementation(this.proxy.address);
  48. expect(implementationAddress).to.be.equal(this.implementationV1.address);
  49. });
  50. });
  51. describe('#upgrade', function () {
  52. context('with unauthorized account', function () {
  53. it('fails to upgrade', async function () {
  54. await expectRevert(
  55. this.proxyAdmin.upgrade(this.proxy.address, this.implementationV2.address, { from: anotherAccount }),
  56. 'caller is not the owner',
  57. );
  58. });
  59. });
  60. context('with authorized account', function () {
  61. it('upgrades implementation', async function () {
  62. await this.proxyAdmin.upgrade(this.proxy.address, this.implementationV2.address, { from: proxyAdminOwner });
  63. const implementationAddress = await this.proxyAdmin.getProxyImplementation(this.proxy.address);
  64. expect(implementationAddress).to.be.equal(this.implementationV2.address);
  65. });
  66. });
  67. });
  68. describe('#upgradeAndCall', function () {
  69. context('with unauthorized account', function () {
  70. it('fails to upgrade', async function () {
  71. const callData = new ImplV1('').contract.methods['initializeNonPayable(uint256)'](1337).encodeABI();
  72. await expectRevert(
  73. this.proxyAdmin.upgradeAndCall(this.proxy.address, this.implementationV2.address, callData,
  74. { from: anotherAccount }
  75. ),
  76. 'caller is not the owner',
  77. );
  78. });
  79. });
  80. context('with authorized account', function () {
  81. context('with invalid callData', function () {
  82. it('fails to upgrade', async function () {
  83. const callData = '0x12345678';
  84. await expectRevert.unspecified(
  85. this.proxyAdmin.upgradeAndCall(this.proxy.address, this.implementationV2.address, callData,
  86. { from: proxyAdminOwner }
  87. ),
  88. );
  89. });
  90. });
  91. context('with valid callData', function () {
  92. it('upgrades implementation', async function () {
  93. const callData = new ImplV1('').contract.methods['initializeNonPayable(uint256)'](1337).encodeABI();
  94. await this.proxyAdmin.upgradeAndCall(this.proxy.address, this.implementationV2.address, callData,
  95. { from: proxyAdminOwner }
  96. );
  97. const implementationAddress = await this.proxyAdmin.getProxyImplementation(this.proxy.address);
  98. expect(implementationAddress).to.be.equal(this.implementationV2.address);
  99. });
  100. });
  101. });
  102. });
  103. });