Skip to content

Commit d62a255

Browse files
committed
v0.7
1 parent a4caa78 commit d62a255

26 files changed

+3139
-563
lines changed

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
black==23.1a1
22
cairo-lang==0.11.2
33
web3==5.31.3
4+
pytest==7.4.4

scripts/build-cairo.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ pushd $(dirname $0)/..
33
set -e
44
mkdir -p cairo_contracts
55

6+
scripts/starknet-compile.py src --contract-path src::strk::erc20_lockable::ERC20Lockable cairo_contracts/ERC20Lockable.sierra
67
scripts/starknet-compile.py src --contract-path src::update_712_vars_eic::Update712VarsEIC cairo_contracts/Update712VarsEIC.sierra
78
scripts/starknet-compile.py src --contract-path src::roles_init_eic::RolesExternalInitializer cairo_contracts/RolesExternalInitializer.sierra
89
scripts/starknet-compile.py src --contract-path src::legacy_bridge_eic::LegacyBridgeUpgradeEIC cairo_contracts/LegacyBridgeUpgradeEIC.sierra
910
scripts/starknet-compile.py src --contract-path src::token_bridge::TokenBridge cairo_contracts/TokenBridge.sierra
10-
scripts/starknet-compile.py src --contract-path openzeppelin::token::erc20::presets::erc20votes::ERC20VotesPreset cairo_contracts/ERC20VotesPreset.sierra
11+
scripts/starknet-compile.py src --contract-path openzeppelin::token::erc20::presets::erc20_votes_lock::ERC20VotesLock cairo_contracts/ERC20VotesLock.sierra
1112
scripts/starknet-compile.py src --contract-path openzeppelin::token::erc20_v070::erc20::ERC20 cairo_contracts/ERC20.sierra
1213
set +e
1314
popd

src/cairo/err_msg.cairo

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,17 @@ mod ERC20Errors {
99

1010
mod AccessErrors {
1111
const INVALID_MINTER: felt252 = 'INVALID_MINTER_ADDRESS';
12+
const INVALID_TOKEN: felt252 = 'INVALID_TOKEN_ADDRESS';
1213
const CALLER_MISSING_ROLE: felt252 = 'CALLER_IS_MISSING_ROLE';
1314
const ZERO_ADDRESS: felt252 = 'INVALID_ACCOUNT_ADDRESS';
1415
const ALREADY_INITIALIZED: felt252 = 'ROLES_ALREADY_INITIALIZED';
1516
const ZERO_ADDRESS_GOV_ADMIN: felt252 = 'ZERO_PROVISIONAL_GOV_ADMIN';
17+
const ONLY_APP_GOVERNOR: felt252 = 'ONLY_APP_GOVERNOR';
18+
const ONLY_OPERATOR: felt252 = 'ONLY_OPERATOR';
19+
const ONLY_TOKEN_ADMIN: felt252 = 'ONLY_TOKEN_ADMIN';
1620
const ONLY_UPGRADE_GOVERNOR: felt252 = 'ONLY_UPGRADE_GOVERNOR';
21+
const ONLY_SECURITY_ADMIN: felt252 = 'ONLY_SECURITY_ADMIN';
22+
const ONLY_SECURITY_AGENT: felt252 = 'ONLY_SECURITY_AGENT';
1723
const ONLY_MINTER: felt252 = 'MINTER_ONLY';
1824
const ONLY_SELF_CAN_RENOUNCE: felt252 = 'ONLY_SELF_CAN_RENOUNCE';
1925
const GOV_ADMIN_CANNOT_RENOUNCE: felt252 = 'GOV_ADMIN_CANNOT_SELF_REMOVE';

src/cairo/legacy_bridge_tester.cairo

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,34 +145,29 @@ mod LegacyBridgeTester {
145145
impl internals of _internals {
146146
fn only_upgrade_governor(self: @ContractState) {}
147147

148-
// Returns if finalized.
149148
fn is_finalized(self: @ContractState) -> bool {
150149
self.finalized.read()
151150
}
152151

153-
// Sets the implementation as finalized.
154152
fn finalize(ref self: ContractState) {
155153
self.finalized.write(true);
156154
}
157155

158156

159-
// Sets the implementation activation time.
160157
fn set_impl_activation_time(
161158
ref self: ContractState, implementation_data: ImplementationData, activation_time: u64
162159
) {
163160
let impl_key = calc_impl_key(:implementation_data);
164161
self.impl_activation_time.write(impl_key, activation_time);
165162
}
166163

167-
// Returns the implementation activation time.
168164
fn get_impl_expiration_time(
169165
self: @ContractState, implementation_data: ImplementationData
170166
) -> u64 {
171167
let impl_key = calc_impl_key(:implementation_data);
172168
self.impl_expiration_time.read(impl_key)
173169
}
174170

175-
// Sets the implementation expiration time.
176171
fn set_impl_expiration_time(
177172
ref self: ContractState, implementation_data: ImplementationData, expiration_time: u64
178173
) {

src/cairo/legacy_eic_test.cairo

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ mod legacy_eic_test {
1010
use serde::Serde;
1111
use starknet::class_hash::{ClassHash, class_hash_const};
1212
use starknet::{ContractAddress, EthAddress, EthAddressZeroable, syscalls::deploy_syscall};
13-
use openzeppelin::token::erc20::presets::erc20votes::ERC20VotesPreset::{
13+
use openzeppelin::token::erc20::presets::erc20_votes_lock::ERC20VotesLock::{
1414
DAPP_NAME, DAPP_VERSION
1515
};
1616

@@ -24,7 +24,7 @@ mod legacy_eic_test {
2424
use src::roles_interface::{IRolesDispatcher, IRolesDispatcherTrait};
2525
use src::test_utils::test_utils::{
2626
caller, get_roles, get_token_bridge, set_contract_address_as_caller, get_replaceable,
27-
simple_deploy_l2_token, DEFAULT_UPGRADE_DELAY
27+
simple_deploy_token, DEFAULT_UPGRADE_DELAY
2828
};
2929
use src::token_bridge_interface::{ITokenBridgeDispatcher, ITokenBridgeDispatcherTrait};
3030
use src::token_bridge::TokenBridge;
@@ -181,8 +181,8 @@ mod legacy_eic_test {
181181
#[test]
182182
#[available_gas(30000000)]
183183
fn test_happy_path() {
184-
let l2_token = simple_deploy_l2_token();
185-
let tester_address = deploy_legacy_tester(l2_token);
184+
let l2_token = simple_deploy_token();
185+
let tester_address = deploy_legacy_tester(:l2_token);
186186
let impl_data = token_bridge_w_eic_implementation_data(
187187
l1_token: L1_TOKEN_ADDRESS(), :l2_token,
188188
);
@@ -191,7 +191,7 @@ mod legacy_eic_test {
191191
);
192192

193193
let token_bridge = get_token_bridge(tester_address);
194-
let l1_token = token_bridge.get_l1_token(l2_token);
194+
let l1_token = token_bridge.get_l1_token(:l2_token);
195195
let l2_token_actual = token_bridge.get_l2_token(L1_TOKEN_ADDRESS());
196196
assert(L1_TOKEN_ADDRESS() == l1_token, 'L1_ZEROED');
197197
assert(l2_token == l2_token_actual, 'L2_ZEROED');
@@ -206,7 +206,7 @@ mod legacy_eic_test {
206206
add_impl_and_replace_to(replaceable_address: tester1, :implementation_data);
207207

208208
// Tester 1 roles are not initialzied, and gov admin not set.
209-
let roles1 = get_roles(tester1);
209+
let roles1 = get_roles(contract_address: tester1);
210210
assert(!roles1.is_governance_admin(caller()), 'Roles should not be initialized');
211211
assert(!roles1.is_upgrade_governor(caller()), 'Roles should not be initialized');
212212
assert(!roles1.is_security_admin(caller()), 'Roles should not be initialized');
@@ -217,7 +217,7 @@ mod legacy_eic_test {
217217
add_impl_and_replace_to(replaceable_address: tester2, :implementation_data);
218218

219219
// Tester 2 roles are initialized and gov admin assigned.
220-
let roles = get_roles(tester2);
220+
let roles = get_roles(contract_address: tester2);
221221
assert(roles.is_governance_admin(caller()), 'Roles should be initialized');
222222
assert(roles.is_upgrade_governor(caller()), 'Roles should be initialized');
223223
assert(roles.is_security_admin(caller()), 'Roles should be initialized');
@@ -322,7 +322,7 @@ mod legacy_eic_test {
322322
#[available_gas(30000000)]
323323
fn test_upgrade_an_upgraded() {
324324
// Test failing to upgrade twice.
325-
let l2_token = simple_deploy_l2_token();
325+
let l2_token = simple_deploy_token();
326326
let tester_address = deploy_legacy_tester(l2_token);
327327
let impl_data = token_bridge_w_eic_implementation_data(
328328
l1_token: L1_TOKEN_ADDRESS(), :l2_token,

src/cairo/lib.cairo

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
// STRK Token (ERC20Lockable).
2+
mod strk;
3+
14
// Interfaces.
25
mod access_control_interface;
36
mod token_bridge_admin_interface;
47
mod token_bridge_interface;
58
mod erc20_interface;
69
mod mintable_token_interface;
10+
mod mintable_lock_interface;
711
mod replaceability_interface;
812
mod roles_interface;
913
mod receiver_interface;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use starknet::ContractAddress;
2+
3+
#[starknet::interface]
4+
trait IMintableLock<TContractState> {
5+
fn permissioned_lock_and_delegate(
6+
ref self: TContractState, account: ContractAddress, delegatee: ContractAddress, amount: u256
7+
);
8+
}
9+
10+
#[starknet::interface]
11+
trait ILockingContract<TContractState> {
12+
fn set_locking_contract(ref self: TContractState, locking_contract: ContractAddress);
13+
fn get_locking_contract(self: @TContractState) -> ContractAddress;
14+
}
15+
16+
#[starknet::interface]
17+
trait ILockAndDelegate<TContractState> {
18+
fn lock_and_delegate(ref self: TContractState, delegatee: ContractAddress, amount: u256);
19+
fn lock_and_delegate_by_sig(
20+
ref self: TContractState,
21+
account: ContractAddress,
22+
delegatee: ContractAddress,
23+
amount: u256,
24+
nonce: felt252,
25+
expiry: u64,
26+
signature: Array<felt252>
27+
);
28+
}
29+
30+
#[starknet::interface]
31+
trait ITokenLock<TContractState> {
32+
fn lock(ref self: TContractState, amount: u256);
33+
fn unlock(ref self: TContractState, amount: u256);
34+
}
35+
36+
#[derive(Copy, Drop, PartialEq, starknet::Event)]
37+
struct Locked {
38+
#[key]
39+
account: ContractAddress,
40+
amount: u256
41+
}
42+
43+
#[derive(Copy, Drop, PartialEq, starknet::Event)]
44+
struct Unlocked {
45+
#[key]
46+
account: ContractAddress,
47+
amount: u256
48+
}

src/cairo/permissioned_token_test.cairo

Lines changed: 6 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@ mod permissioned_token_test {
99
use integer::BoundedInt;
1010
use serde::Serde;
1111
use starknet::{contract_address_const, ContractAddress, syscalls::deploy_syscall};
12+
use src::err_msg::AccessErrors as AccessErrors;
1213

1314
use super::super::mintable_token_interface::{
1415
IMintableTokenDispatcher, IMintableTokenDispatcherTrait
1516
};
1617
use super::super::erc20_interface::{IERC20Dispatcher, IERC20DispatcherTrait};
1718
use super::super::test_utils::test_utils::{
18-
get_erc20_token, deploy_l2_votes_token, deploy_l2_token, get_mintable_token,
19-
get_l2_token_deployment_calldata
19+
get_erc20_token, deploy_l2_token, get_mintable_token, get_l2_token_deployment_calldata
2020
};
2121

22-
use openzeppelin::token::erc20::presets::erc20votes::ERC20VotesPreset;
22+
use openzeppelin::token::erc20::presets::erc20_votes_lock::ERC20VotesLock;
2323
use openzeppelin::token::erc20_v070::erc20::ERC20;
2424

2525
fn _l2_erc20(initial_supply: u256) -> ContractAddress {
@@ -28,23 +28,6 @@ mod permissioned_token_test {
2828
deploy_l2_token(:initial_owner, :permitted_minter, :initial_supply)
2929
}
3030

31-
fn _l2_votes_erc20(initial_supply: u256) -> ContractAddress {
32-
let initial_owner = starknet::contract_address_const::<10>();
33-
let permitted_minter = starknet::contract_address_const::<20>();
34-
deploy_l2_votes_token(:initial_owner, :permitted_minter, :initial_supply)
35-
}
36-
37-
#[test]
38-
#[available_gas(30000000)]
39-
fn test_votes_erc20_successful_permitted_mint() {
40-
let initial_owner = starknet::contract_address_const::<10>();
41-
let permitted_minter = starknet::contract_address_const::<20>();
42-
let l2_token = deploy_l2_votes_token(
43-
:initial_owner, :permitted_minter, initial_supply: 1000
44-
);
45-
_successful_permitted_mint(:l2_token, :initial_owner, :permitted_minter);
46-
}
47-
4831
#[test]
4932
#[available_gas(30000000)]
5033
fn test_erc20_successful_permitted_mint() {
@@ -85,21 +68,6 @@ mod permissioned_token_test {
8568
);
8669
}
8770

88-
#[test]
89-
#[should_panic(expected: ('u256_add Overflow', 'ENTRYPOINT_FAILED',))]
90-
#[available_gas(30000000)]
91-
fn test_votes_erc20_overflowing_permitted_mint() {
92-
// Setup.
93-
let initial_owner = starknet::contract_address_const::<10>();
94-
let permitted_minter = starknet::contract_address_const::<20>();
95-
96-
// Deploy the l2 token contract.
97-
let l2_token = deploy_l2_votes_token(
98-
:initial_owner, :permitted_minter, initial_supply: BoundedInt::max()
99-
);
100-
_overflowing_permitted_mint(:l2_token, :initial_owner, :permitted_minter);
101-
}
102-
10371
#[test]
10472
#[should_panic(expected: ('u256_add Overflow', 'ENTRYPOINT_FAILED',))]
10573
#[available_gas(30000000)]
@@ -125,14 +93,6 @@ mod permissioned_token_test {
12593
mintable_token.permissioned_mint(account: mint_recipient, amount: 1);
12694
}
12795

128-
#[test]
129-
#[should_panic(expected: ('MINTER_ONLY', 'ENTRYPOINT_FAILED',))]
130-
#[available_gas(30000000)]
131-
fn test_votes_erc20_unpermitted_permitted_mint() {
132-
let l2_token = _l2_votes_erc20(initial_supply: 1000);
133-
_unpermitted_permitted_mint(:l2_token);
134-
}
135-
13696
#[test]
13797
#[should_panic(expected: ('MINTER_ONLY', 'ENTRYPOINT_FAILED',))]
13898
#[available_gas(30000000)]
@@ -170,19 +130,10 @@ mod permissioned_token_test {
170130
.unwrap_err()
171131
.span();
172132
assert(error_message.len() == 2, 'UNEXPECTED_ERROR_LEN_MISMATCH');
173-
assert(error_message.at(0) == @'INVALID_MINTER_ADDRESS', 'INVALID_MINTER_ADDRESS_ERROR');
174-
assert(error_message.at(1) == @'CONSTRUCTOR_FAILED', 'CONSTRUCTOR_ERROR_MISMATCH');
175-
}
176-
177-
#[test]
178-
#[available_gas(30000000)]
179-
fn test_votes_erc20_successful_permitted_burn() {
180-
let initial_owner = starknet::contract_address_const::<10>();
181-
let permitted_minter = starknet::contract_address_const::<20>();
182-
let l2_token = deploy_l2_votes_token(
183-
:initial_owner, :permitted_minter, initial_supply: 1000
133+
assert(
134+
error_message.at(0) == @AccessErrors::INVALID_MINTER, 'INVALID_MINTER_ADDRESS_ERROR'
184135
);
185-
_successful_permitted_burn(:l2_token, :initial_owner, :permitted_minter);
136+
assert(error_message.at(1) == @'CONSTRUCTOR_FAILED', 'CONSTRUCTOR_ERROR_MISMATCH');
186137
}
187138

188139
#[test]
@@ -216,21 +167,6 @@ mod permissioned_token_test {
216167
assert(erc20_token.total_supply() == expected_after, 'TOTAL_SUPPLY_PERM_BURN_ERROR');
217168
}
218169

219-
#[test]
220-
#[should_panic(expected: ('u256_sub Overflow', 'ENTRYPOINT_FAILED',))]
221-
#[available_gas(30000000)]
222-
fn test_votes_erc20_exceeding_amount_permitted_burn() {
223-
// Setup.
224-
let initial_owner = starknet::contract_address_const::<10>();
225-
let permitted_minter = starknet::contract_address_const::<20>();
226-
227-
// Deploy the l2 token contract.
228-
let l2_token = deploy_l2_votes_token(
229-
:initial_owner, :permitted_minter, initial_supply: 1000
230-
);
231-
_exceeding_amount_permitted_burn(:l2_token, :initial_owner, :permitted_minter);
232-
}
233-
234170
#[test]
235171
#[should_panic(expected: ('u256_sub Overflow', 'ENTRYPOINT_FAILED',))]
236172
#[available_gas(30000000)]
@@ -254,21 +190,6 @@ mod permissioned_token_test {
254190
mintable_token.permissioned_burn(account: initial_owner, amount: 1001);
255191
}
256192

257-
#[test]
258-
#[should_panic(expected: ('MINTER_ONLY', 'ENTRYPOINT_FAILED',))]
259-
#[available_gas(30000000)]
260-
fn test_votes_erc20_unpermitted_permitted_burn() {
261-
// Setup.
262-
let initial_owner = starknet::contract_address_const::<10>();
263-
let permitted_minter = starknet::contract_address_const::<20>();
264-
265-
// Deploy the l2 token contract.
266-
let l2_token = deploy_l2_votes_token(
267-
:initial_owner, :permitted_minter, initial_supply: 1000
268-
);
269-
_unpermitted_permitted_burn(:l2_token, :initial_owner, :permitted_minter);
270-
}
271-
272193
#[test]
273194
#[should_panic(expected: ('MINTER_ONLY', 'ENTRYPOINT_FAILED',))]
274195
#[available_gas(30000000)]

0 commit comments

Comments
 (0)