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

Add starknet auth #138

Merged
merged 10 commits into from
May 26, 2022
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
run: |
sudo apt install -y libgmp3-dev
python -m pip install --upgrade pip
pip install starknet-devnet==0.1.19
pip install starknet-devnet==0.2.1
pip install werkzeug==2.0.3
pip install openzeppelin-cairo-contracts
pip install marshmallow-dataclass==8.5.3 --force
Expand Down
10 changes: 3 additions & 7 deletions contracts/starknet/authenticators/eth_tx.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ from starkware.cairo.common.memcpy import memcpy
from starkware.cairo.common.math import assert_not_equal
from contracts.starknet.lib.eth_address import EthAddress
from contracts.starknet.lib.hash_array import hash_array
from contracts.starknet.lib.execute import execute

# Address of the StarkNet Commit L1 contract which acts as the origin address of the messages sent to this contract.
@storage_var
Expand Down Expand Up @@ -42,7 +43,7 @@ func commit{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr :
end

@external
func execute{syscall_ptr : felt*, range_check_ptr, pedersen_ptr : HashBuiltin*}(
func authenticate{syscall_ptr : felt*, range_check_ptr, pedersen_ptr : HashBuiltin*}(
target : felt, function_selector : felt, calldata_len : felt, calldata : felt*
):
alloc_locals
Expand All @@ -65,11 +66,6 @@ func execute{syscall_ptr : felt*, range_check_ptr, pedersen_ptr : HashBuiltin*}(
# Clear the hash from the contract by writing the zero address to the mapping.
commit_store.write(hash, EthAddress(0))
# Execute the function call with calldata supplied.
call_contract(
contract_address=target,
function_selector=function_selector,
calldata_size=calldata_len,
calldata=calldata,
)
execute(target, function_selector, calldata_len, calldata)
return ()
end
36 changes: 36 additions & 0 deletions contracts/starknet/authenticators/starknet_sig.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
%lang starknet

from contracts.starknet.lib.execute import execute
from contracts.starknet.lib.felt_to_uint256 import felt_to_uint256
from starkware.starknet.common.syscalls import get_caller_address
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
from starkware.cairo.common.math import assert_not_zero
from starkware.cairo.common.uint256 import uint256_eq
# from openzeppelin.account.IAccount import IAccount

# TODO: change `hash` to actual data, not simply the hash
@external
func authenticate{syscall_ptr : felt*, range_check_ptr, bitwise_ptr : BitwiseBuiltin*}(
hash : felt,
sig_len : felt,
sig : felt*,
target : felt,
function_selector : felt,
calldata_len : felt,
calldata : felt*,
) -> ():
# Voter address or proposer address should be located in calldata[0]
let user_address = calldata[0]

# Will throw if signature is invalid
# with_attr error_message("Invalid signature"):
# IAccount.is_valid_signature(
# contract_address=user_address, hash=hash, signature_len=sig_len, signature=sig
# )
# end

# Call the contract
execute(target, function_selector, calldata_len, calldata)

return ()
end
22 changes: 22 additions & 0 deletions contracts/starknet/authenticators/starknet_tx.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
%lang starknet
from contracts.starknet.lib.execute import execute
from contracts.starknet.lib.felt_to_uint256 import felt_to_uint256
from starkware.starknet.common.syscalls import get_caller_address
from starkware.cairo.common.cairo_builtins import BitwiseBuiltin
from starkware.cairo.common.uint256 import uint256_eq

@external
func authenticate{syscall_ptr : felt*, range_check_ptr, bitwise_ptr : BitwiseBuiltin*}(
target : felt, function_selector : felt, calldata_len : felt, calldata : felt*
) -> ():
let (caller_address) = get_caller_address()

with_attr error_message("Incorrect caller"):
assert caller_address = calldata[0]
end

# Call the contract
execute(target, function_selector, calldata_len, calldata)

return ()
end
11 changes: 3 additions & 8 deletions contracts/starknet/authenticators/vanilla.cairo
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
%lang starknet
from starkware.starknet.common.syscalls import call_contract
from contracts.starknet.lib.execute import execute

# Forwards `data` to `target` without verifying anything.
@external
func execute{syscall_ptr : felt*, range_check_ptr}(
func authenticate{syscall_ptr : felt*, range_check_ptr}(
target : felt, function_selector : felt, calldata_len : felt, calldata : felt*
) -> ():
# TODO: Actually verify the signature

# Call the contract
call_contract(
contract_address=target,
function_selector=function_selector,
calldata_size=calldata_len,
calldata=calldata,
)
execute(target, function_selector, calldata_len, calldata)

return ()
end
17 changes: 17 additions & 0 deletions contracts/starknet/lib/execute.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
%lang starknet
from starkware.starknet.common.syscalls import call_contract

# Forwards `data` to `target` without verifying anything.
@external
func execute{syscall_ptr : felt*, range_check_ptr}(
target : felt, function_selector : felt, calldata_len : felt, calldata : felt*
) -> ():
call_contract(
contract_address=target,
function_selector=function_selector,
calldata_size=calldata_len,
calldata=calldata,
)

return ()
end
11 changes: 9 additions & 2 deletions contracts/starknet/space.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ 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 import (
assert_lt, assert_le, assert_nn, assert_not_zero, assert_lt_felt
assert_lt,
assert_le,
assert_nn,
assert_not_zero,
assert_lt_felt,
)

from contracts.starknet.interfaces.i_voting_strategy import i_voting_strategy
Expand All @@ -23,7 +27,10 @@ from contracts.starknet.lib.array2d import Immutable2DArray, construct_array2d,
from contracts.starknet.lib.slot_key import get_slot_key

from openzeppelin.access.ownable import (
Ownable_only_owner, Ownable_transfer_ownership, Ownable_get_owner, Ownable_initializer
Ownable_only_owner,
Ownable_transfer_ownership,
Ownable_get_owner,
Ownable_initializer,
)

#
Expand Down
11 changes: 9 additions & 2 deletions contracts/starknet/voting_strategies/single_slot_proof.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,15 @@ func get_voting_power{
let (local fact_registry_addr) = fact_registry_store.read()

# Decoding voting strategy parameters
let (slot, proof_sizes_bytes_len, proof_sizes_bytes, proof_sizes_words_len, proof_sizes_words,
proofs_concat_len, proofs_concat) = decode_param_array(user_params_len, user_params)
let (
slot,
proof_sizes_bytes_len,
proof_sizes_bytes,
proof_sizes_words_len,
proof_sizes_words,
proofs_concat_len,
proofs_concat,
) = decode_param_array(user_params_len, user_params)

# Checking that the parameters array is valid and then extracting the individual parameters
# For the single slot proof strategy, the parameters array is length 2 where the first element is the
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
https://github.com/starkware-libs/cairo-lang/releases/download/v0.8.0/cairo-lang-0.8.0.zip
https://github.com/starkware-libs/cairo-lang/releases/download/v0.8.2/cairo-lang-0.8.2.zip
openzeppelin-cairo-contracts
10 changes: 5 additions & 5 deletions test/crosschain/eth_tx_auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ describe('L1 interaction with Snapshot X', function () {
//Checking that the L1 -> L2 message has been propogated
expect((await starknet.devnet.flush()).consumed_messages.from_l1).to.have.a.lengthOf(1);
// Creating proposal
await ethTxAuthenticator.invoke('execute', {
await ethTxAuthenticator.invoke('authenticate', {
target: target,
function_selector: propose_selector,
calldata: propose_calldata,
Expand All @@ -115,14 +115,14 @@ describe('L1 interaction with Snapshot X', function () {
await starknetCommit.commit(propose_commit);

await starknet.devnet.flush();
await ethTxAuthenticator.invoke('execute', {
await ethTxAuthenticator.invoke('authenticate', {
target: target,
function_selector: propose_selector,
calldata: propose_calldata,
});
// Second execute should fail
try {
await ethTxAuthenticator.invoke('execute', {
await ethTxAuthenticator.invoke('authenticate', {
target: target,
function_selector: propose_selector,
calldata: propose_calldata,
Expand All @@ -141,7 +141,7 @@ describe('L1 interaction with Snapshot X', function () {
await starknetCommit.commit(propose_commit);
await starknet.devnet.flush();
try {
await ethTxAuthenticator.invoke('execute', {
await ethTxAuthenticator.invoke('authenticate', {
target: target,
function_selector: propose_selector,
calldata: propose_calldata,
Expand All @@ -160,7 +160,7 @@ describe('L1 interaction with Snapshot X', function () {
await starknetCommit.commit(propose_commit);
await starknet.devnet.flush();
try {
await ethTxAuthenticator.invoke('execute', {
await ethTxAuthenticator.invoke('authenticate', {
target: target,
function_selector: propose_selector,
calldata: propose_calldata,
Expand Down
6 changes: 3 additions & 3 deletions test/crosschain/zodiac.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
VITALIK_ADDRESS,
VITALIK_STRING_ADDRESS,
vanillaSetup,
EXECUTE_METHOD,
AUTHENTICATE_METHOD,
PROPOSAL_METHOD,
VOTE_METHOD,
} from '../starknet/shared/setup';
Expand Down Expand Up @@ -131,7 +131,7 @@ describe('Create proposal, cast vote, and send execution to l1', function () {
];

// -- Creates a proposal --
await authContract.invoke(EXECUTE_METHOD, {
await authContract.invoke(AUTHENTICATE_METHOD, {
target: BigInt(spaceContract.address),
function_selector: BigInt(getSelectorFromName(PROPOSAL_METHOD)),
calldata,
Expand All @@ -142,7 +142,7 @@ describe('Create proposal, cast vote, and send execution to l1', function () {
const voter_address = proposer_address;
const votingParamsAll: bigint[][] = [[]];
const votingParamsAllFlat = flatten2DArray(votingParamsAll);
await authContract.invoke(EXECUTE_METHOD, {
await authContract.invoke(AUTHENTICATE_METHOD, {
target: BigInt(spaceContract.address),
function_selector: BigInt(getSelectorFromName(VOTE_METHOD)),
calldata: [
Expand Down
13 changes: 9 additions & 4 deletions test/starknet/executor_whitelist.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@ import { stark } from 'starknet';
import { SplitUint256, FOR } from './shared/types';
import { strToShortStringArr } from '@snapshot-labs/sx';
import { expect } from 'chai';
import { vanillaSetup, VITALIK_ADDRESS, EXECUTE_METHOD, PROPOSAL_METHOD } from './shared/setup';
import {
vanillaSetup,
VITALIK_ADDRESS,
AUTHENTICATE_METHOD,
PROPOSAL_METHOD,
} from './shared/setup';
import { flatten2DArray } from './shared/helpers';
import { StarknetContract } from 'hardhat/types';
import { Account } from '@shardlabs/starknet-hardhat-plugin/dist/account';
Expand Down Expand Up @@ -75,7 +80,7 @@ describe('Whitelist testing', () => {

it('Should create a proposal for a whitelisted executor', async () => {
{
await vanillaAuthenticator.invoke(EXECUTE_METHOD, {
await vanillaAuthenticator.invoke(AUTHENTICATE_METHOD, {
target: spaceContract,
function_selector: BigInt(getSelectorFromName(PROPOSAL_METHOD)),
calldata,
Expand All @@ -92,7 +97,7 @@ describe('Whitelist testing', () => {
try {
// Try to create a proposal, should fail because it just got removed
// from the whitelist
await vanillaAuthenticator.invoke(EXECUTE_METHOD, {
await vanillaAuthenticator.invoke(AUTHENTICATE_METHOD, {
target: spaceContract,
function_selector: BigInt(getSelectorFromName(PROPOSAL_METHOD)),
calldata,
Expand All @@ -107,7 +112,7 @@ describe('Whitelist testing', () => {
to_add: [BigInt(zodiacRelayer.address), VITALIK_ADDRESS],
});

await vanillaAuthenticator.invoke(EXECUTE_METHOD, {
await vanillaAuthenticator.invoke(AUTHENTICATE_METHOD, {
target: spaceContract,
function_selector: BigInt(getSelectorFromName(PROPOSAL_METHOD)),
calldata: calldata2,
Expand Down
Loading