Skip to content

Commit

Permalink
feat: add proposal core
Browse files Browse the repository at this point in the history
  • Loading branch information
ericnordelo committed Oct 11, 2024
1 parent 7117e98 commit 5eb6f28
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 12 deletions.
4 changes: 4 additions & 0 deletions packages/governance/src/governor.cairo
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
pub mod governor;
pub mod interface;
pub mod proposal_core;

pub use governor::GovernorComponent;
pub use proposal_core::ProposalCore;
7 changes: 6 additions & 1 deletion packages/governance/src/governor/governor.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@
///
/// Core of the governance system.
#[starknet::component]
pub mod GovernorComponent {}
pub mod GovernorComponent {
use crate::governor::ProposalCore;

#[storage]
pub struct Storage {}
}
79 changes: 79 additions & 0 deletions packages/governance/src/governor/proposal_core.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts for Cairo v0.17.0 (governance/governor/proposal_core.cairo)

use starknet::ContractAddress;
use starknet::storage_access::StorePacking;

#[derive(Copy, Drop, Serde)]
pub struct ProposalCore {
proposer: ContractAddress,
vote_start: u64,
vote_duration: u64,
executed: bool,
canceled: bool,
eta_seconds: u64
}

const _2_POW_184: felt252 = 0x10000000000000000000000000000000000000000000000;
const _2_POW_120: felt252 = 0x1000000000000000000000000000000;
const _2_POW_119: felt252 = 0x800000000000000000000000000000;
const _2_POW_118: felt252 = 0x400000000000000000000000000000;
const _2_POW_54: felt252 = 0x40000000000000;

const _64_BITS_MASK: u256 = 0xffffffffffffffff;
const _1_BIT_MASK: u256 = 0x1;

/// Packs a ProposalCore into a (felt252, felt252).
///
/// The packing is done as follows:
///
/// - The first felt of the tuple contains `proposer` serialized.
/// - The second felt of the tuple contains `vote_start`, `vote_duration`, `executed`, `canceled`
/// and `eta_seconds` organized as presented next.
/// - `vote_start` is stored at range [4,67] bits (0-indexed), taking the most significant usable
/// bits.
/// - `vote_duration` is stored at range [68, 131], following `vote_start`.
/// - `executed` is stored at range [132, 132], following `vote_duration`.
/// - `canceled` is stored at range [133, 133], following `executed`.
/// - `eta_seconds` is stored at range [134, 197], following `canceled`.
///
/// NOTE: In the second felt252, the first four bits are skipped to avoid representation errors due
/// to `felt252` max value being a bit less than a 252 bits number max value
/// (https://docs.starknet.io/documentation/architecture_and_concepts/Cryptography/p-value/).
impl ProposalCoreStorePacking of StorePacking<ProposalCore, (felt252, felt252)> {
fn pack(value: ProposalCore) -> (felt252, felt252) {
let proposal = value;

// shift-left to reach the corresponding positions
let vote_start = proposal.vote_start.into() * _2_POW_184;
let vote_duration = proposal.vote_duration.into() * _2_POW_120;
let executed = proposal.executed.into() * _2_POW_119;
let canceled = proposal.canceled.into() * _2_POW_118;
let eta_seconds = proposal.eta_seconds.into() * _2_POW_54;

let second_felt = vote_start + vote_duration + executed + canceled + eta_seconds;

(proposal.proposer.into(), second_felt)
}

fn unpack(value: (felt252, felt252)) -> ProposalCore {
let (proposer, second_felt) = value;
let second_felt: u256 = second_felt.into();

// shift-right and mask to extract the corresponding values
let vote_start: u256 = (second_felt / _2_POW_184.into()) & _64_BITS_MASK;
let vote_duration: u256 = (second_felt / _2_POW_120.into()) & _64_BITS_MASK;
let executed: u256 = (second_felt / _2_POW_119.into()) & _1_BIT_MASK;
let canceled: u256 = (second_felt / _2_POW_118.into()) & _1_BIT_MASK;
let eta_seconds: u256 = (second_felt / _2_POW_54.into()) & _64_BITS_MASK;

ProposalCore {
proposer: proposer.try_into().unwrap(),
vote_start: vote_start.try_into().unwrap(),
vote_duration: vote_duration.try_into().unwrap(),
executed: executed > 0,
canceled: canceled > 0,
eta_seconds: eta_seconds.try_into().unwrap()
}
}
}
6 changes: 2 additions & 4 deletions packages/token/src/erc1155/erc1155.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,7 @@ pub mod ERC1155Component {
/// - `from` is not the zero address.
/// - `to` is not the zero address.
/// - If `to` refers to a non-account contract, it must implement
/// `IERC1155Receiver::on_ERC1155_received`
/// and return the required magic value.
/// `IERC1155Receiver::on_ERC1155_received` and return the required magic value.
///
/// Emits a `TransferSingle` event.
fn safe_transfer_from(
Expand Down Expand Up @@ -213,8 +212,7 @@ pub mod ERC1155Component {
/// - `to` is not the zero address.
/// - `token_ids` and `values` must have the same length.
/// - If `to` refers to a non-account contract, it must implement
/// `IERC1155Receiver::on_ERC1155_batch_received`
/// and return the acceptance magic value.
/// `IERC1155Receiver::on_ERC1155_batch_received` and return the acceptance magic value.
///
/// Emits either a `TransferSingle` or a `TransferBatch` event, depending on the length of
/// the array arguments.
Expand Down
18 changes: 11 additions & 7 deletions packages/utils/src/structs/checkpoint.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -160,21 +160,25 @@ impl CheckpointImpl of CheckpointTrait {
}

const _2_POW_184: felt252 = 0x10000000000000000000000000000000000000000000000;
const _128_BITS_MASK: u256 = 0xffffffffffffffffffffffffffffffff;

/// Packs a Checkpoint into a (felt252, felt252).
///
/// The packing is done as follows:
///
/// - The first felt of the tuple contains `key` and `value.low`.
/// - In this first felt, the first four bits are skipped to avoid representation errors due
/// to `felt252` max value being a bit less than a 252 bits number max value
/// (https://docs.starknet.io/documentation/architecture_and_concepts/Cryptography/p-value/).
/// - `key` is stored at range [4,67] bits (0-indexed), taking the most significant usable bits.
/// - `value.low` is stored at range [124, 251], taking the less significant bits (at the end).
/// - `value.high` is stored as the second tuple element.
///
/// NOTE: In this first felt, the first four bits are skipped to avoid representation errors due
/// to `felt252` max value being a bit less than a 252 bits number max value
/// (https://docs.starknet.io/documentation/architecture_and_concepts/Cryptography/p-value/).
impl CheckpointStorePacking of StorePacking<Checkpoint, (felt252, felt252)> {
fn pack(value: Checkpoint) -> (felt252, felt252) {
let checkpoint = value;
// shift-left by 184 bits

// shift-left to reach the corresponding position
let key = checkpoint.key.into() * _2_POW_184;
let key_and_low = key + checkpoint.value.low.into();

Expand All @@ -183,11 +187,11 @@ impl CheckpointStorePacking of StorePacking<Checkpoint, (felt252, felt252)> {

fn unpack(value: (felt252, felt252)) -> Checkpoint {
let (key_and_low, high) = value;

let key_and_low: u256 = key_and_low.into();
// shift-right by 184 bits

// shift-right and mask to extract the corresponding values
let key: u256 = key_and_low / _2_POW_184.into();
let low = key_and_low & 0xffffffffffffffffffffffffffffffff;
let low = key_and_low & _128_BITS_MASK;

Checkpoint {
key: key.try_into().unwrap(),
Expand Down

0 comments on commit 5eb6f28

Please sign in to comment.