Skip to content

Commit ffa768c

Browse files
Merge pull request #1 from radixdlt/main
Merge from Main repo
2 parents baa7215 + ba70519 commit ffa768c

File tree

1,999 files changed

+284414
-7
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,999 files changed

+284414
-7
lines changed

.gitignore

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Visual studio code
22
.vscode
3+
.history
34

45
# macOS folder attributes
56
.DS_Store
@@ -10,4 +11,8 @@ Cargo.lock
1011
**/*.rs.bk
1112

1213
# Flamegraph profiles
13-
flamegraph.svg
14+
flamegraph.svg
15+
3-lending/LendingDApp/node_modules
16+
3-lending/LendingDApp/public/lending_dapp.wasm
17+
3-lending/LendingDApp/public/loan_application.wasm
18+
3-lending/LendingDApp/TODO.md

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "3-lending/rai-test/RAI-Scrypto-Lending-Platform-PTE"]
2+
path = 3-lending/rai-test/RAI-Scrypto-Lending-Platform-PTE
3+
url = [email protected]:dekentz/RAI-Scrypto-Lending-Platform-PTE.git

1-exchanges/RaDEX/Cargo.toml

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ version = "0.2.0"
44
edition = "2021"
55

66
[dependencies]
7-
sbor = { path = "/Users/omarabdulla/radix/radixdlt-scrypto/sbor" }
8-
scrypto = { path = "/Users/omarabdulla/radix/radixdlt-scrypto/scrypto" }
7+
sbor = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.4.0" }
8+
scrypto = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.4.0" }
99

1010
[dev-dependencies]
11-
radix-engine = { path = "/Users/omarabdulla/radix/radixdlt-scrypto/radix-engine" }
11+
radix-engine = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.4.0" }
1212

1313
[profile.release]
1414
opt-level = 's' # Optimize for size.
@@ -18,3 +18,4 @@ panic = 'abort' # Abort on panic.
1818

1919
[lib]
2020
crate-type = ["cdylib", "lib"]
21+

1-exchanges/dexianswap/src/pmm.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -382,10 +382,10 @@ blueprint! {
382382
sqrt = Decimal::one();
383383
}
384384
else {
385-
sqrt = Decimal::one(); // sqrt( Decimal::one() + ki * delta / v1 )
385+
sqrt = ((Decimal::one() + ki * delta / v1) as f64).sqrt().floor() as Decimal;
386386
}
387387

388-
return v1 * (Decimal::one() + sqrt - Decimal::one() / (Decimal(2) * k))
388+
return v1 * (Decimal::one() + sqrt - Decimal::one() / (Decimal(2) * k));
389389
}
390390

391391
fn solve_quadratic_function_for_trade(
@@ -432,7 +432,8 @@ blueprint! {
432432
b_abs = b_abs - part2;
433433
}
434434

435-
let square_root = Decimal::one(); //sqrt(b_abs * b_abs + Decimal(4) * (Decimal::one() - k) * v0 * v0 * k);
435+
// let square_root = sqrt(b_abs * b_abs + Decimal(4) * (Decimal::one() - k) * v0 * v0 * k);
436+
let square_root = ((b_abs * b_abs + Decimal(4) * (Decimal::one() - k) * v0 * v0 * k) as f64).sqrt().floor() as Decimal;
436437

437438
let denominator = Decimal(2) * (Decimal::one() - k);
438439
let mut numerator:Decimal = Decimal::zero();

2-oracles/DexianOracle/Cargo.toml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[package]
2+
name = "DexianOracle"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
sbor = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.4.1" }
8+
scrypto = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.4.1" }
9+
10+
[dev-dependencies]
11+
radix-engine = { git = "https://github.com/radixdlt/radixdlt-scrypto", tag = "v0.4.1" }
12+
13+
[profile.release]
14+
opt-level = 's' # Optimize for size.
15+
lto = true # Enable Link Time Optimization.
16+
codegen-units = 1 # Reduce number of codegen units to increase optimizations.
17+
panic = 'abort' # Abort on panic.
18+
strip = "debuginfo" # Strip debug info.
19+
20+
[lib]
21+
crate-type = ["cdylib", "lib"]

2-oracles/DexianOracle/readme.md

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# DeXianOracle
2+
3+
[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
4+
5+
## Basic Request Model
6+
7+
![Basic Request Model](res/basic_req_model.png)
8+
9+
#### roles
10+
###### Consumer
11+
The `Consumer` is the Radix Engine component that consumes/uses data from the oracle. It make a request to send a certain data consumption request to an explicit oracle component, which also carries some parameter data that can be passed back.
12+
13+
###### OracleComponent
14+
The `oracle` component, which is the hub of the entire architecture, is responsible for logged consumer requests, managing authorizations and revocations to data providers, as well as accepting data pushed by data providers and initiating callbacks to connected consumers while delivering the data they need, such as: prices, contest results, etc.
15+
16+
It implements permission management through the badge design pattern, and the address with the specified badge can only push data to the `oracle`.
17+
18+
###### DataProvider
19+
The data provider, which is the functional unit that feeds data from the off-chain data to the on-chain `oracle`, needs to present a specific badge before pushing the data inside the `oracle` component.
20+
21+
#### process
22+
1. Request with callback
23+
24+
Spend some `XRD`, call Oracle's `request_price` method, and wait for the callback.
25+
26+
2. Oracle request
27+
3. Feed
28+
4. Fulfil oracle request
29+
30+
The data provider calls `feed_price` to push the price to the `oracle` and trigger a callback.
31+
32+
5. callback
33+
34+
Callback as requested by the caller of 'request_price`
35+
36+
37+
## Decentralized Model
38+
39+
![Decentralized Request Model](res/decentrailized_model.png)
40+
41+
It directly calls `get_price` to get the corresponding price and the epoch (timestamp) when the price was generated.
42+
43+
44+
45+
## Test (command line)
46+
47+
``` shell
48+
resim reset
49+
result=$(resim new-account)
50+
export user_account=$(echo $result|grep "Account component address: "|awk -F ": " '{print $2}'|awk -F " " '{print $1}')
51+
export user_account_private=$(echo $result|grep "Account component address: "|awk -F "Private key: " '{print $2}')
52+
53+
result=$(resim publish ".")
54+
export pkg=$(echo $result | awk -F ": " '{print $2}')
55+
56+
result=$(resim call-function $pkg DeXianOracle new 20)
57+
export comp=$(echo $result | awk -F "Component: " '{print $2}' | awk -F " " '{print $1}')
58+
export badge=$(echo $result | awk -F "Resource: " '{print $2}' | awk -F " " '{print $1}')
59+
60+
resim run transactions/user_account_feed.rtm
61+
62+
result=$(resim new-account)
63+
export user_account2=$(echo $result|grep "Account component address: "|awk -F ": " '{print $2}'|awk -F " " '{print $1}')
64+
export user_account2_private=$(echo $result|grep "Account component address: "|awk -F "Private key: " '{print $2}')
65+
66+
resim set-default-account $user_account2 $user_account2_private
67+
68+
resim call-method $comp 'get_price' 'XRD/USD'
69+
70+
resim set-default-account $user_account $user_account_private
71+
72+
resim run transactions/user_account2_request.rtm
73+
74+
75+
```
76+
50.9 KB
Loading
Loading

2-oracles/DexianOracle/src/lib.rs

+163
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
use scrypto::prelude::*;
2+
3+
blueprint! {
4+
struct DeXianOracle {
5+
/// This is just a reular admin badge, for register/remove DataProvider
6+
admin_badge: ResourceAddress,
7+
8+
// /// DataProvider badge ResourceDef
9+
// dataprovider_badge_def: ResourceDef,
10+
// minter
11+
callback_minter: Vault,
12+
13+
// /// DataProvider badge ResourceDef
14+
// dataprovider_badge_def: ResourceDef,
15+
16+
/// callbacks
17+
callback_vaults: Vault,
18+
19+
/// callback that have not yet been triggered
20+
unfilful_vec: Vec<NonFungibleId>,
21+
22+
/// fee
23+
fee: Decimal,
24+
25+
/// oracle (price, epoch_at) for XRD/USD
26+
price_map: HashMap<String, (Decimal, u64)>,
27+
28+
/// balance(fee) vault
29+
vault: Vault
30+
}
31+
32+
impl DeXianOracle {
33+
pub fn new(
34+
fee: Decimal
35+
) -> (ComponentAddress, Bucket) {
36+
assert!( fee > Decimal::zero(), "invalid fee value.");
37+
38+
let admin_badge : Bucket = ResourceBuilder::new_fungible()
39+
.metadata("name","DeXianOracle Admin Badge").metadata("symbol","DXADM")
40+
.initial_supply(Decimal::ONE);
41+
42+
let minter_badge = ResourceBuilder::new_fungible()
43+
.divisibility(DIVISIBILITY_NONE)
44+
.initial_supply(Decimal::ONE);
45+
46+
let callback_bucket = ResourceBuilder::new_non_fungible()
47+
.metadata("name", "DeXianOracle Callback").metadata("symbol", "DXCB")
48+
.mintable(rule!(require(admin_badge.resource_address())), LOCKED)
49+
.burnable(rule!(require(admin_badge.resource_address())), LOCKED)
50+
.no_initial_supply();
51+
52+
let component = Self {
53+
admin_badge: admin_badge.resource_address(),
54+
price_map: HashMap::new(),
55+
vault: Vault::new(RADIX_TOKEN),
56+
callback_vaults: Vault::new(callback_bucket),
57+
unfilful_vec: Vec::new(),
58+
callback_minter: Vault::with_bucket(minter_badge),
59+
fee
60+
}.instantiate();
61+
62+
let access_rules = AccessRules::new()
63+
.method("feed_price", rule!(require(admin_badge.resource_address())))
64+
.method("withdraw_fee", rule!(require(admin_badge.resource_address())))
65+
.method("request_price", rule!(allow_all))
66+
.method("get_price", rule!(allow_all));
67+
// .method("register_dataprovider", rule(!require(admin_badge.resource_address())))
68+
// .method("remove_dataprovider", rule(!require(admin_badge.resource_address())));
69+
70+
(component.add_access_check(access_rules).globalize(), admin_badge)
71+
72+
}
73+
74+
pub fn feed_price(&mut self, pair: String, price: String) -> bool {
75+
let epoch_at = Runtime::current_epoch();
76+
let dec_price = Decimal::from(price.clone());
77+
self.price_map.insert(pair.clone(), (dec_price, epoch_at));
78+
self.filfull_request(&pair, price.clone(), epoch_at);
79+
true
80+
}
81+
82+
pub fn get_price(&self, pair:String) -> (Decimal, u64){
83+
assert!(self.price_map.contains_key(&pair), "the pair not exists!");
84+
*self.price_map.get(&pair).unwrap()
85+
}
86+
87+
pub fn request_price(&mut self, fee: Bucket, pair: String, component: ComponentAddress,
88+
method: String, arg: String) -> NonFungibleId {
89+
assert!(fee.amount() >= self.fee, "Fees are lower than required!");
90+
self.vault.put(fee);
91+
92+
let callback_id = NonFungibleId::random();
93+
let callback_data = CallbackData::new_instance(callback_id.clone(), component, method, pair, args!(arg));
94+
95+
let callback = self.callback_minter.authorize(|| {
96+
let rm = borrow_resource_manager!(self.callback_vaults.resource_address());
97+
rm.mint_non_fungible(&callback_id, callback_data)
98+
});
99+
// Store the Callback NFR inside this component
100+
self.callback_vaults.put(callback);
101+
self.unfilful_vec.push(callback_id.clone());
102+
callback_id
103+
}
104+
105+
pub fn withdraw_fee(&mut self, amount: Decimal) -> Bucket{
106+
assert!(self.vault.amount () < amount, "balance insufficient!");
107+
108+
self.vault.take(amount)
109+
}
110+
111+
fn filfull_request(&mut self, pair: &String, price: String, epoch_at: u64) {
112+
let mut i = 0;
113+
while i < self.unfilful_vec.len() {
114+
if self.callback_vaults.non_fungible_ids().contains(&self.unfilful_vec[i]){
115+
let callback = self.callback_vaults.take_non_fungible(&self.unfilful_vec[i]);
116+
let callback_data = callback.non_fungible::<CallbackData>().data();
117+
if callback_data.pair.eq(pair) {
118+
callback_data.call(&price, epoch_at);
119+
self.unfilful_vec.remove(i);
120+
}
121+
i += 1;
122+
}
123+
}
124+
}
125+
}
126+
}
127+
128+
#[derive(NonFungibleData)]
129+
pub struct CallbackData {
130+
/// request id
131+
pub id: NonFungibleId,
132+
133+
pub pair: String,
134+
135+
/// The target component of the callback
136+
pub component: ComponentAddress,
137+
138+
/// The target method of the callback
139+
pub method: String,
140+
141+
/// The args that should be passed to the target method
142+
pub args: Vec<Vec<u8>>,
143+
}
144+
145+
impl CallbackData {
146+
147+
pub fn new_instance(id: NonFungibleId, component: ComponentAddress,
148+
method: String, pair: String, args: Vec<Vec<u8>>
149+
) -> Self {
150+
151+
Self {
152+
args: args.to_vec(),
153+
pair,
154+
id,
155+
component,
156+
method
157+
}
158+
}
159+
160+
pub fn call(&self, price: &String, epoch_at: u64){
161+
Runtime::call_method(self.component, &self.method, args![price.clone(), epoch_at, self.args.to_vec()]);
162+
}
163+
}

2-oracles/DexianOracle/tests/lib.rs

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use radix_engine::ledger::*;
2+
use radix_engine::transaction::*;
3+
use scrypto::prelude::*;
4+
5+
#[test]
6+
fn test_hello() {
7+
// Set up environment.
8+
let mut ledger = InMemorySubstateStore::with_bootstrap();
9+
let mut executor = TransactionExecutor::new(&mut ledger, false);
10+
let (pk, sk, account) = executor.new_account();
11+
let package = executor.publish_package(compile_package!()).unwrap();
12+
13+
// Test the `instantiate_hello` function.
14+
let transaction1 = TransactionBuilder::new()
15+
.call_function(package, "Hello", "instantiate_hello", args![])
16+
.build(executor.get_nonce([pk]))
17+
.sign([&sk]);
18+
let receipt1 = executor.validate_and_execute(&transaction1).unwrap();
19+
println!("{:?}\n", receipt1);
20+
assert!(receipt1.result.is_ok());
21+
22+
// Test the `free_token` method.
23+
let component = receipt1.new_component_addresses[0];
24+
let transaction2 = TransactionBuilder::new()
25+
.call_method(component, "free_token", args![])
26+
.call_method_with_all_resources(account, "deposit_batch")
27+
.build(executor.get_nonce([pk]))
28+
.sign([&sk]);
29+
let receipt2 = executor.validate_and_execute(&transaction2).unwrap();
30+
println!("{:?}\n", receipt2);
31+
assert!(receipt2.result.is_ok());
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
CALL_METHOD
2+
ComponentAddress("${user_account}")
3+
"withdraw_by_amount"
4+
Decimal("20")
5+
ResourceAddress("030000000000000000000000000000000000000000000000000004");
6+
7+
CALL_METHOD
8+
ComponentAddress("${user_account}")
9+
"create_proof"
10+
ResourceAddress("${badge}");
11+
12+
TAKE_FROM_WORKTOP_BY_AMOUNT Decimal("20") ResourceAddress("030000000000000000000000000000000000000000000000000004") Bucket("request_fee");
13+
CALL_METHOD ComponentAddress("${comp}") "request_price" Bucket("request_fee") "XRD/USD" ComponentAddress("${user_account}") "deposit_batch" "xxx";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
CALL_METHOD
2+
ComponentAddress("${user_account}")
3+
"create_proof"
4+
ResourceAddress("${badge}");
5+
6+
7+
CALL_METHOD ComponentAddress("${comp}") "feed_price" "XRD/USD" "0.0813";

0 commit comments

Comments
 (0)