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

BCI-1259: [REVISED] upgrade test #262

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
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
1 change: 1 addition & 0 deletions contracts/src/libraries.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ mod ownable;
mod access_control;
mod token;
mod upgradeable;
mod mocks;
2 changes: 2 additions & 0 deletions contracts/src/libraries/mocks.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
mod mock_upgradeable;
mod mock_non_upgradeable;
11 changes: 11 additions & 0 deletions contracts/src/libraries/mocks/mock_non_upgradeable.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#[contract]
mod MockNonUpgradeable {

#[constructor]
fn constructor() {}

#[view]
fn bar() -> bool {
true
}
}
21 changes: 21 additions & 0 deletions contracts/src/libraries/mocks/mock_upgradeable.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use starknet::class_hash::ClassHash;

#[contract]
mod MockUpgradeable {
use starknet::class_hash::ClassHash;

use chainlink::libraries::upgradeable::Upgradeable;

#[constructor]
fn constructor() {}

#[view]
fn foo() -> bool {
true
}

#[external]
fn upgrade(new_impl: ClassHash) {
Upgradeable::upgrade(new_impl)
}
}
72 changes: 72 additions & 0 deletions contracts/test/upgradeable.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { expect } from 'chai'
import { starknet } from 'hardhat'
import { StarknetContract, Account, StarknetContractFactory } from 'hardhat/types/runtime'
import { account, expectInvokeError, expectSuccessOrDeclared, expectCallError } from '@chainlink/starknet'
import { ec } from 'starknet'

describe('upgradeable', function () {
this.timeout(1_000_000)

let owner: Account
let nonOwner: Account
const opts = account.makeFunderOptsFromEnv()
const funder = new account.Funder(opts)
let upgradeableFactory: StarknetContractFactory
let nonUpgradeableFactory: StarknetContractFactory
let upgradeableContract: StarknetContract


// should be beforeeach, but that'd be horribly slow. Just remember that the tests are not idempotent
before(async function () {
owner = await starknet.OpenZeppelinAccount.createAccount()

await funder.fund([
{ account: owner.address, amount: 1e21 },
])
await owner.deployAccount()

upgradeableFactory = await starknet.getContractFactory('mock_upgradeable')
await expectSuccessOrDeclared(owner.declare(upgradeableFactory, { maxFee: 1e20 }))

nonUpgradeableFactory = await starknet.getContractFactory('mock_non_upgradeable')
await expectSuccessOrDeclared(owner.declare(nonUpgradeableFactory, { maxFee: 1e20 }))
})

describe('Upgrade contract', () => {

beforeEach(async () => {
upgradeableContract = await owner.deploy(upgradeableFactory)
})

it('succeeds if class hash exists', async () => {
expect((await upgradeableContract.call('foo')).response).to.equal(true)

const newClassHash = await nonUpgradeableFactory.getClassHash()

await owner.invoke(
upgradeableContract,
'upgrade',
{
new_impl: newClassHash
}
)

// should error because the contract has upgraded and no longer has foo function
await expectCallError(upgradeableContract.call('foo'))

const afterUpgradeContract = nonUpgradeableFactory.getContractAt(upgradeableContract.address)
expect((await afterUpgradeContract.call('bar')).response).to.equal(true)
})

it('reverts if new implementation class hash does not exist', async () => {
expect((await upgradeableContract.call('foo')).response).to.equal(true)
const nonExistentClassHash = ec.starkCurve.pedersen(777, 777)

// class hash is not declared: StarknetErrorCode.UNDECLARED_CLASS
await expectInvokeError(
owner.invoke(upgradeableContract, 'upgrade', { new_impl: nonExistentClassHash })
)

})
})
})
Loading