Skip to content

Commit e6f0011

Browse files
committed
feat(price_feeds/starknet): simplify contract, use STRK, add CI
1 parent a103c25 commit e6f0011

File tree

6 files changed

+65
-41
lines changed

6 files changed

+65
-41
lines changed

.github/workflows/ci-starknet.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Starknet tests
2+
on:
3+
pull_request:
4+
paths:
5+
- price_feeds/starknet/**
6+
push:
7+
branches:
8+
- main
9+
paths:
10+
- price_feeds/starknet/**
11+
jobs:
12+
check:
13+
name: Starknet contract tests
14+
runs-on: ubuntu-latest
15+
defaults:
16+
run:
17+
working-directory: price_feeds/starknet/send_usd/contract
18+
steps:
19+
- uses: actions/checkout@v3
20+
- name: Install Scarb
21+
uses: software-mansion/setup-scarb@v1
22+
with:
23+
tool-versions: price_feeds/starknet/send_usd/contract/.tool-versions
24+
- name: Install Starknet Foundry
25+
uses: foundry-rs/setup-snfoundry@v3
26+
with:
27+
tool-versions: price_feeds/starknet/send_usd/contract/.tool-versions
28+
- name: Install Starkli
29+
run: curl https://get.starkli.sh | sh && . ~/.config/.starkli/env && starkliup -v $(awk '/starkli/{print $2}' .tool-versions)
30+
- name: Install Katana
31+
run: curl -L https://install.dojoengine.org | bash && PATH="$PATH:$HOME/.config/.dojo/bin" dojoup -v $(awk '/dojo/{print $2}' .tool-versions)
32+
- name: Check formatting
33+
run: scarb fmt --check
34+
- name: Build contract
35+
run: scarb build
36+
- name: Check ABI files
37+
run: |
38+
cat target/dev/send_usd_send_usd.contract_class.json | jq .abi > /tmp/send_usd.json
39+
if ! cmp --silent /tmp/send_usd.json ../client/src/abi/send_usd.json ; then
40+
>&2 echo ABI file mismatch for client/src/abi/send_usd.json
41+
exit 1
42+
fi

price_feeds/starknet/send_usd/client/src/abi/send_usd.json

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,8 @@
6767
"type": "core::starknet::contract_address::ContractAddress"
6868
},
6969
{
70-
"name": "eth_erc20_address",
70+
"name": "strk_erc20_address",
7171
"type": "core::starknet::contract_address::ContractAddress"
72-
},
73-
{
74-
"name": "eth_usd_price_id",
75-
"type": "core::integer::u256"
7672
}
7773
]
7874
},

price_feeds/starknet/send_usd/client/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ async function main() {
5858
});
5959

6060
const priceId =
61-
'0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace'; // ETH/USD
61+
'0x6a182399ff70ccf3e06024898942028204125a819e519a335ffa4579e66cd870'; // STRK/USD
6262

6363
console.log('querying pyth update');
6464
// Get the latest values of the price feeds as json objects.

price_feeds/starknet/send_usd/contract/Scarb.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@ edition = "2023_11"
66
[dependencies]
77
starknet = ">=2.5.4"
88
openzeppelin = { git = "https://github.com/OpenZeppelin/cairo-contracts.git", tag = "v0.10.0" }
9-
10-
# TODO: replace with tag after release
119
pyth = { git = "https://github.com/pyth-network/pyth-crosschain.git", tag = "pyth-starknet-contract-v0.1.0" }
1210

1311
[[target.starknet-contract]]

price_feeds/starknet/send_usd/contract/deploy/local_deploy

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,12 @@ fi
2626
send_usd_hash=$(starkli declare --watch target/dev/send_usd_send_usd.contract_class.json)
2727
${sleep}
2828

29-
# ETH/USD
30-
price_feed_id=0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace
31-
32-
price_feed_u128_low=$(
33-
python3 -c "print(${price_feed_id} % (1<<128))"
34-
)
35-
price_feed_u128_high=$(
36-
python3 -c "print(${price_feed_id} // (1<<128))"
37-
)
29+
# STRK/USD
30+
price_feed_id=0x6a182399ff70ccf3e06024898942028204125a819e519a335ffa4579e66cd870
3831

3932
send_usd_address=$(starkli deploy --watch "${send_usd_hash}" \
4033
"${PYTH_ADDRESS}" \
4134
"${fee_token_address}" \
42-
"${price_feed_u128_low}" "${price_feed_u128_high}" \
4335
)
4436
${sleep}
4537

price_feeds/starknet/send_usd/contract/src/lib.cairo

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use pyth::ByteBuffer;
33

44
#[starknet::interface]
55
pub trait ISendUsd<T> {
6-
/// Sends ETH from the caller to the destination. The amount of ETH will be equivalent
7-
/// to the specified amount of USD, converted using the last available ETH/USD price from Pyth.
8-
/// `price_update` should be the latest available price update for the ETH/USD price feed.
6+
/// Sends STRK from the caller to the destination. The amount of STRK will be equivalent
7+
/// to the specified amount of USD, converted using the last available STRK/USD price from Pyth.
8+
/// `price_update` should be the latest available price update for the STRK/USD price feed.
99
/// The caller needs to set up sufficient allowance for this contract.
1010
fn send_usd(
1111
ref self: T, destination: ContractAddress, amount_in_usd: u256, price_update: ByteBuffer
@@ -20,29 +20,23 @@ mod send_usd {
2020
use openzeppelin::token::erc20::interface::{IERC20CamelDispatcherTrait, IERC20CamelDispatcher};
2121

2222
const MAX_PRICE_AGE: u64 = 3600; // 1 hour
23-
const WEI_PER_ETH: u256 = 1000000000000000000;
23+
const TOKENS_PER_STRK: u256 = 1000000000000000000;
2424

2525
#[storage]
2626
struct Storage {
2727
pyth_address: ContractAddress,
28-
eth_erc20_address: ContractAddress,
29-
eth_usd_price_id: u256,
28+
strk_erc20_address: ContractAddress,
3029
}
3130

3231
/// Initializes the contract.
3332
/// `pyth_address` is the address of the deployed Pyth account.
34-
/// `eth_erc20_address` is the address of the ERC20 token account for the ETH token.
35-
/// `eth_usd_price_id` is the ID of Pyth's price feed for ETH/USD.
33+
/// `strk_erc20_address` is the address of the ERC20 token account for the STRK token.
3634
#[constructor]
3735
fn constructor(
38-
ref self: ContractState,
39-
pyth_address: ContractAddress,
40-
eth_erc20_address: ContractAddress,
41-
eth_usd_price_id: u256,
36+
ref self: ContractState, pyth_address: ContractAddress, strk_erc20_address: ContractAddress,
4237
) {
4338
self.pyth_address.write(pyth_address);
44-
self.eth_erc20_address.write(eth_erc20_address);
45-
self.eth_usd_price_id.write(eth_usd_price_id);
39+
self.strk_erc20_address.write(strk_erc20_address);
4640
}
4741

4842
#[abi(embed_v0)]
@@ -54,34 +48,36 @@ mod send_usd {
5448
price_update: ByteBuffer
5549
) {
5650
let pyth = IPythDispatcher { contract_address: self.pyth_address.read() };
57-
let eth_erc20 = IERC20CamelDispatcher {
58-
contract_address: self.eth_erc20_address.read()
51+
let strk_erc20 = IERC20CamelDispatcher {
52+
contract_address: self.strk_erc20_address.read()
5953
};
6054
let caller = get_caller_address();
6155
let contract = get_contract_address();
6256

63-
let pyth_fee = pyth.get_update_fee(price_update.clone(), eth_erc20.contract_address);
64-
if !eth_erc20.transferFrom(caller, contract, pyth_fee) {
57+
let pyth_fee = pyth.get_update_fee(price_update.clone(), strk_erc20.contract_address);
58+
if !strk_erc20.transferFrom(caller, contract, pyth_fee) {
6559
panic_with_felt252('insufficient allowance for fee');
6660
}
67-
if !eth_erc20.approve(pyth.contract_address, pyth_fee) {
61+
if !strk_erc20.approve(pyth.contract_address, pyth_fee) {
6862
panic_with_felt252('approve failed');
6963
}
7064

7165
pyth.update_price_feeds(price_update);
7266

67+
/// `strk_usd_price_id` is the ID of Pyth's price feed for STRK/USD.
68+
let strk_usd_price_id =
69+
0x6a182399ff70ccf3e06024898942028204125a819e519a335ffa4579e66cd870;
7370
let price = pyth
74-
.get_price_no_older_than(self.eth_usd_price_id.read(), MAX_PRICE_AGE)
71+
.get_price_no_older_than(strk_usd_price_id, MAX_PRICE_AGE)
7572
.unwrap_with_felt252();
7673

7774
let price_u64: u64 = price.price.try_into().unwrap();
78-
let amount_in_wei = WEI_PER_ETH
75+
let amount_in_wei = TOKENS_PER_STRK
7976
* exp10((-price.expo).try_into().unwrap())
8077
* amount_in_usd
8178
/ price_u64.into();
8279

83-
let transfer_ok = eth_erc20
84-
.transferFrom(caller, destination, amount_in_wei);
80+
let transfer_ok = strk_erc20.transferFrom(caller, destination, amount_in_wei);
8581
if !transfer_ok {
8682
panic_with_felt252('insufficient allowance');
8783
}

0 commit comments

Comments
 (0)