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

Felt math #362

Merged
merged 9 commits into from
Oct 19, 2022
Merged
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
2 changes: 0 additions & 2 deletions contracts/starknet/Authenticators/EthSigSessionKey.cairo
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
%lang starknet

from starkware.starknet.common.syscalls import get_block_timestamp
from starkware.cairo.common.cairo_builtins import HashBuiltin, SignatureBuiltin, BitwiseBuiltin
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.math import split_felt, assert_le, assert_not_zero
from starkware.cairo.common.cairo_keccak.keccak import (
keccak_add_uint256s,
keccak_bigend,
Expand Down
14 changes: 8 additions & 6 deletions contracts/starknet/lib/session_key.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from starkware.starknet.common.syscalls import get_block_timestamp
from starkware.cairo.common.uint256 import Uint256
from starkware.cairo.common.cairo_builtins import HashBuiltin, SignatureBuiltin, BitwiseBuiltin
from starkware.cairo.common.math import assert_le, assert_not_zero
from starkware.cairo.common.math import assert_lt, assert_not_zero, assert_nn_le
from starkware.cairo.common.alloc import alloc

from contracts.starknet.lib.stark_eip191 import StarkEIP191
Expand Down Expand Up @@ -134,7 +134,7 @@ namespace SessionKey {
let (end_timestamp) = SessionKey_end_timestamp_store.read(session_public_key);
let (current_timestamp) = get_block_timestamp();
with_attr error_message("SessionKey: Session has ended") {
assert_le(current_timestamp, end_timestamp);
assert_lt(current_timestamp, end_timestamp);
}
return (eth_address,);
}
Expand All @@ -154,13 +154,15 @@ namespace SessionKey {
func _register{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
eth_address: felt, session_public_key: felt, session_duration: felt
) {
SessionKey_owner_store.write(session_public_key, eth_address);
// It is valid to give a session duration of zero - if so it means the session is only valid during the same block as when it was registered
let (current_timestamp) = get_block_timestamp();
let end_timestamp = current_timestamp + session_duration;
with_attr error_message("SessionKey: Overflow in Session duration") {
assert_le(current_timestamp, end_timestamp);
with_attr error_message("SessionKey: Invalid session duration") {
// Asserts that 0 <= session_duration <= end_timestamp < RANGE_CHECK_BOUND
assert_nn_le(session_duration, end_timestamp);
}
SessionKey_end_timestamp_store.write(session_public_key, current_timestamp + session_duration);
SessionKey_owner_store.write(session_public_key, eth_address);
SessionKey_end_timestamp_store.write(session_public_key, end_timestamp);
session_key_registered.emit(eth_address, session_public_key, session_duration);
return ();
}
Expand Down
6 changes: 2 additions & 4 deletions contracts/starknet/lib/single_slot_proof.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

// from starkware.cairo.common.cairo_builtins import HashBuiltin, BitwiseBuiltin
// from starkware.cairo.common.uint256 import Uint256, uint256_add
// from starkware.cairo.common.math import unsigned_div_rem, assert_nn_le
// from starkware.cairo.common.math import unsigned_div_rem, assert_le

// from contracts.starknet.fossil.contracts.starknet.types import StorageSlot
// from contracts.starknet.lib.general_address import Address
Expand Down Expand Up @@ -122,7 +122,7 @@
// proofs_concat_len: felt,
// proofs_concat: felt*,
// ) {
// assert_nn_le(5, param_array_len);
// assert_le(5, param_array_len);
// let slot: StorageSlot = StorageSlot(
// param_array[0], param_array[1], param_array[2], param_array[3]
// );
Expand All @@ -133,8 +133,6 @@
// let proof_sizes_words = param_array + 5 + num_nodes;
// let proofs_concat = param_array + 5 + 2 * num_nodes;
// let proofs_concat_len = param_array_len - 5 - 2 * num_nodes;
// // Could add check by summing proof_sizes_words array and checking that it is equal to proofs_concat_len
// // However this seems like unnecessary computation to do on-chain (proofs will fail if invalid params are sent anyway)
// return (
// slot,
// proof_sizes_bytes_len,
Expand Down
25 changes: 7 additions & 18 deletions contracts/starknet/lib/voting.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,12 @@ from starkware.cairo.common.uint256 import Uint256, uint256_add, uint256_lt, uin
from starkware.cairo.common.bool import TRUE, FALSE
from starkware.cairo.common.hash_state import hash_init, hash_update
from starkware.cairo.common.math_cmp import is_le
from starkware.cairo.common.math import (
assert_lt,
assert_le,
assert_nn,
assert_nn_le,
assert_not_zero,
assert_lt_felt,
assert_not_equal,
)
from starkware.cairo.common.math import assert_lt, assert_le, assert_nn, assert_not_zero

// OpenZeppelin
from openzeppelin.access.ownable.library import Ownable
from openzeppelin.account.library import Account, AccountCallArray, Call
from openzeppelin.security.safemath.library import SafeUint256

// Interfaces
from contracts.starknet.Interfaces.IVotingStrategy import IVotingStrategy
Expand Down Expand Up @@ -486,8 +479,7 @@ namespace Voting {

// Make sure `choice` is a valid choice
with_attr error_message("Voting: Invalid choice") {
assert_le(Choice.FOR, choice);
assert_le(choice, Choice.ABSTAIN);
assert (choice - Choice.ABSTAIN) * (choice - Choice.FOR) * (choice - Choice.AGAINST) = 0;
Orland0x marked this conversation as resolved.
Show resolved Hide resolved
}

// Reconstruct the voting params 2D array (1 sub array per strategy) from the flattened version.
Expand All @@ -505,20 +497,16 @@ namespace Voting {
);

let (no_voting_power) = uint256_eq(Uint256(0, 0), user_voting_power);

with_attr error_message("Voting: No voting power for user") {
assert no_voting_power = 0;
}

let (previous_voting_power) = Voting_vote_power_store.read(proposal_id, choice);
let (new_voting_power, overflow) = uint256_add(user_voting_power, previous_voting_power);

with_attr error_message("Voting: Overflow in voting power") {
pscott marked this conversation as resolved.
Show resolved Hide resolved
assert overflow = 0;
let (new_voting_power) = SafeUint256.add(user_voting_power, previous_voting_power);
}

Voting_vote_power_store.write(proposal_id, choice, new_voting_power);

Voting_vote_registry_store.write(proposal_id, voter_address, 1);

// Emit event
Expand Down Expand Up @@ -696,6 +684,7 @@ namespace Voting {
}
} else {
// Quorum has been reached: set proposal outcome accordingly
// Note: The proposal is rejected if for and against votes are equal.
let (has_passed) = uint256_lt(against, for);

if (has_passed == 1) {
Expand Down Expand Up @@ -1117,7 +1106,7 @@ func unchecked_get_cumulative_voting_power{
let (strategy_address) = Voting_voting_strategies_store.read(strategy_index);

with_attr error_message("Voting: Invalid voting strategy") {
assert_not_equal(strategy_address, 0);
assert_not_zero(strategy_address);
}

// Extract voting params array for the voting strategy specified by the index
Expand Down Expand Up @@ -1190,7 +1179,7 @@ func get_voting_strategy_params{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*,
func decode_execution_params{syscall_ptr: felt*, pedersen_ptr: HashBuiltin*, range_check_ptr}(
execution_params_len: felt, execution_params: felt*
) -> (call_array_len: felt, call_array: AccountCallArray*, calldata_len: felt, calldata: felt*) {
assert_nn_le(4, execution_params_len); // Min execution params length is 4 (corresponding to 1 tx with no calldata)
assert_le(4, execution_params_len); // Min execution params length is 4 (corresponding to 1 tx with no calldata)
let call_array_len = (execution_params[0] - 1) / 4; // Number of calls in the proposal payload
let call_array = cast(&execution_params[1], AccountCallArray*);
let calldata_len = execution_params_len - execution_params[0];
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
https://github.com/starkware-libs/cairo-lang/releases/download/v0.10.0/cairo-lang-0.10.0.zip
openzeppelin-cairo-contracts==0.4.0b0
starknet-devnet==0.3.1
starknet-devnet==0.3.2
8 changes: 4 additions & 4 deletions test/starknet/EthSigSessionKeyAuth.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { expect } from 'chai';
import { StarknetContract, Account } from 'hardhat/types';
import { ec, typedData, hash, Signer } from 'starknet';
import { ethers } from 'hardhat';
import { ethers, starknet } from 'hardhat';
import {
domain,
SessionKey,
Expand Down Expand Up @@ -552,11 +552,11 @@ describe('Ethereum Signature Session Key Auth testing', () => {
}
}).timeout(6000000);

it('Should fail if overflow occurs on the session duration', async () => {
it('Should fail if overflow occurs when calculating the session end timestamp session duration', async () => {
const salt: utils.splitUint256.SplitUint256 = utils.splitUint256.SplitUint256.fromHex(
ethers.utils.hexlify(ethers.utils.randomBytes(4))
);
sessionDuration = '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff';
sessionDuration = '0xfffffffffffffffffffffffffffffffffffffffffffffff'; // Greater than RANGE_CHECK_BOUND
const message: SessionKey = {
address: account.address,
sessionPublicKey: utils.encoding.hexPadRight(sessionPublicKey),
Expand All @@ -578,7 +578,7 @@ describe('Ethereum Signature Session Key Auth testing', () => {
});
throw { message: '' };
} catch (err: any) {
expect(err.message).to.contain('SessionKey: Overflow in Session duration');
expect(err.message).to.contain('SessionKey: Invalid session duration');
}
}).timeout(6000000);
});