-
Notifications
You must be signed in to change notification settings - Fork 111
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #73 from sui-foundation/daniel/adding-kiosk-basics
Adding Kiosk Unit
- Loading branch information
Showing
16 changed files
with
923 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# @generated by Move, please check-in and do not edit manually. | ||
|
||
[move] | ||
version = 0 | ||
manifest_digest = "FC84CCD33DE1E9661DA31B49398152B41FB6772CFBCD634619716A9823846811" | ||
deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" | ||
|
||
dependencies = [ | ||
{ name = "Sui" }, | ||
] | ||
|
||
[[move.package]] | ||
name = "MoveStdlib" | ||
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/move-stdlib" } | ||
|
||
[[move.package]] | ||
name = "Sui" | ||
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/sui-framework" } | ||
|
||
dependencies = [ | ||
{ name = "MoveStdlib" }, | ||
] | ||
|
||
[move.toolchain-version] | ||
compiler-version = "1.21.0" | ||
edition = "legacy" | ||
flavor = "sui" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
[package] | ||
name = "flashloan" | ||
version = "0.0.1" | ||
|
||
# edition = "2024.alpha" # To use the Move 2024 edition, currently in alpha | ||
# license = "" # e.g., "MIT", "GPL", "Apache 2.0" | ||
# authors = ["..."] # e.g., ["Joe Smith ([email protected])", "John Snow ([email protected])"] | ||
|
||
[dependencies] | ||
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "framework/testnet" } | ||
|
||
# For remote import, use the `{ git = "...", subdir = "...", rev = "..." }`. | ||
# Revision can be a branch, a tag, and a commit hash. | ||
# MyRemotePackage = { git = "https://some.remote/host.git", subdir = "remote/path", rev = "main" } | ||
|
||
# For local dependencies use `local = path`. Path is relative to the package root | ||
# Local = { local = "../path/to" } | ||
|
||
# To resolve a version conflict and force a specific version for dependency | ||
# override use `override = true` | ||
# Override = { local = "../conflicting/version", override = true } | ||
|
||
[addresses] | ||
flashloan = "0x0" | ||
sui = "0x2" | ||
|
||
# Named addresses will be accessible in Move as `@name`. They're also exported: | ||
# for example, `std = "0x1"` is exported by the Standard Library. | ||
# alice = "0xA11CE" | ||
|
||
[dev-dependencies] | ||
# The dev-dependencies section allows overriding dependencies for `--test` and | ||
# `--dev` modes. You can introduce test-only dependencies here. | ||
# Local = { local = "../path/to/dev-build" } | ||
|
||
[dev-addresses] | ||
# The dev-addresses section allows overwriting named addresses for the `--test` | ||
# and `--dev` modes. | ||
# alice = "0xB0B" | ||
|
93 changes: 93 additions & 0 deletions
93
unit-five/example_projects/flashloan/sources/flashloan.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
// Copyright (c) Sui Foundation, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
module flashloan::flashloan { | ||
// === Imports === | ||
use sui::sui::SUI; | ||
use sui::coin::{Self, Coin}; | ||
use sui::balance::{Self, Balance}; | ||
use sui::object::{Self, UID}; | ||
use sui::tx_context::{TxContext}; | ||
use sui::transfer::{Self}; | ||
|
||
// === Errors === | ||
|
||
/// For when the loan amount exceed the pool amount | ||
const ELoanAmountExceedPool: u64 = 0; | ||
/// For when the repay amount do not match the initial loan amount | ||
const ERepayAmountInvalid: u64 = 1; | ||
|
||
// === Structs === | ||
|
||
/// A "shared" loan pool. | ||
/// For demonstration purpose, we assume the loan pool only allows SUI. | ||
struct LoanPool has key { | ||
id: UID, | ||
amount: Balance<SUI>, | ||
} | ||
|
||
/// A loan position. | ||
/// This is a hot potato struct, it enforces the users | ||
/// to repay the loan in the end of the transaction or within the same PTB. | ||
struct Loan { | ||
amount: u64, | ||
} | ||
|
||
/// A dummy NFT to represent the flashloan functionality | ||
struct NFT has key{ | ||
id: UID, | ||
price: Balance<SUI>, | ||
} | ||
|
||
fun init(ctx: &mut TxContext) { | ||
let pool = LoanPool { | ||
id: object::new(ctx), | ||
amount: balance::zero() | ||
}; | ||
transfer::share_object(pool); | ||
} | ||
// === Public-Mutative Functions === | ||
|
||
/// Deposit money into loan pool | ||
public fun deposit_pool(pool: &mut LoanPool, deposit: Coin<SUI>) { | ||
balance::join(&mut pool.amount, coin::into_balance(deposit)); | ||
} | ||
|
||
/// Function allows users to borrow from the loan pool. | ||
/// It returns the borrowed [`Coin<SUI>`] and the [`Loan`] position | ||
/// enforcing users to fulfill before the PTB ends. | ||
public fun borrow(pool: &mut LoanPool, amount: u64, ctx: &mut TxContext): (Coin<SUI>, Loan) { | ||
assert!(amount <= balance::value(&pool.amount), ELoanAmountExceedPool); | ||
|
||
( | ||
coin::from_balance(balance::split(&mut pool.amount, amount), ctx), | ||
Loan { | ||
amount | ||
} | ||
) | ||
} | ||
|
||
/// Repay the loan | ||
/// Users must execute this function to ensure the loan is repaid before the transaction ends. | ||
public fun repay(pool: &mut LoanPool, loan: Loan, payment: Coin<SUI>) { | ||
let Loan { amount } = loan; | ||
assert!(coin::value(&payment) == amount, ERepayAmountInvalid); | ||
|
||
balance::join(&mut pool.amount, coin::into_balance(payment)); | ||
} | ||
|
||
/// Mint NFT | ||
public fun mint_nft(payment: Coin<SUI>, ctx: &mut TxContext): NFT { | ||
NFT { | ||
id: object::new(ctx), | ||
price: coin::into_balance(payment), | ||
} | ||
} | ||
|
||
/// Sell NFT | ||
public fun sell_nft(nft: NFT, ctx: &mut TxContext): Coin<SUI> { | ||
let NFT {id, price} = nft; | ||
object::delete(id); | ||
coin::from_balance(price, ctx) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# @generated by Move, please check-in and do not edit manually. | ||
|
||
[move] | ||
version = 0 | ||
manifest_digest = "1FF626947D27118D75E5892ECC965B6EA5D58EF40C92513A237A9F1A2B5F5DDB" | ||
deps_digest = "F8BBB0CCB2491CA29A3DF03D6F92277A4F3574266507ACD77214D37ECA3F3082" | ||
|
||
dependencies = [ | ||
{ name = "Sui" }, | ||
] | ||
|
||
[[move.package]] | ||
name = "MoveStdlib" | ||
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/move-stdlib" } | ||
|
||
[[move.package]] | ||
name = "Sui" | ||
source = { git = "https://github.com/MystenLabs/sui.git", rev = "framework/testnet", subdir = "crates/sui-framework/packages/sui-framework" } | ||
|
||
dependencies = [ | ||
{ name = "MoveStdlib" }, | ||
] | ||
|
||
[move.toolchain-version] | ||
compiler-version = "1.21.0" | ||
edition = "legacy" | ||
flavor = "sui" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
[package] | ||
name = "kiosk" | ||
version = "0.0.1" | ||
|
||
# edition = "2024.alpha" # To use the Move 2024 edition, currently in alpha | ||
# license = "" # e.g., "MIT", "GPL", "Apache 2.0" | ||
# authors = ["..."] # e.g., ["Joe Smith ([email protected])", "John Snow ([email protected])"] | ||
|
||
[dependencies] | ||
Sui = { git = "https://github.com/MystenLabs/sui.git", subdir = "crates/sui-framework/packages/sui-framework", rev = "framework/testnet" } | ||
|
||
# For remote import, use the `{ git = "...", subdir = "...", rev = "..." }`. | ||
# Revision can be a branch, a tag, and a commit hash. | ||
# MyRemotePackage = { git = "https://some.remote/host.git", subdir = "remote/path", rev = "main" } | ||
|
||
# For local dependencies use `local = path`. Path is relative to the package root | ||
# Local = { local = "../path/to" } | ||
|
||
# To resolve a version conflict and force a specific version for dependency | ||
# override use `override = true` | ||
# Override = { local = "../conflicting/version", override = true } | ||
|
||
[addresses] | ||
kiosk = "0x0" | ||
sui = "0x2" | ||
|
||
# Named addresses will be accessible in Move as `@name`. They're also exported: | ||
# for example, `std = "0x1"` is exported by the Standard Library. | ||
# alice = "0xA11CE" | ||
|
||
[dev-dependencies] | ||
# The dev-dependencies section allows overriding dependencies for `--test` and | ||
# `--dev` modes. You can introduce test-only dependencies here. | ||
# Local = { local = "../path/to/dev-build" } | ||
|
||
[dev-addresses] | ||
# The dev-addresses section allows overwriting named addresses for the `--test` | ||
# and `--dev` modes. | ||
# alice = "0xB0B" | ||
|
50 changes: 50 additions & 0 deletions
50
unit-five/example_projects/kiosk/sources/dummy_policy.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// Copyright (c) Sui Foundation, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
// The code is taken here https://github.com/MystenLabs/apps/blob/main/kiosk/docs/creating_a_rule_guide.md#rule-structure-dummy | ||
|
||
module kiosk::dummy_rule { | ||
use sui::coin::Coin; | ||
use sui::sui::SUI; | ||
use sui::transfer_policy::{ | ||
Self as policy, | ||
TransferPolicy, | ||
TransferPolicyCap, | ||
TransferRequest | ||
}; | ||
|
||
/// The Rule Witness; has no fields and is used as a | ||
/// static authorization method for the rule. | ||
struct Rule has drop {} | ||
|
||
/// Configuration struct with any fields (as long as it | ||
/// has `drop`). Managed by the Rule module. | ||
struct Config has store, drop {} | ||
|
||
/// Function that adds a Rule to the `TransferPolicy`. | ||
/// Requires `TransferPolicyCap` to make sure the rules are | ||
/// added only by the publisher of T. | ||
public fun set<T>( | ||
policy: &mut TransferPolicy<T>, | ||
cap: &TransferPolicyCap<T> | ||
) { | ||
policy::add_rule(Rule {}, policy, cap, Config {}) | ||
} | ||
|
||
/// Action function - perform a certain action (any, really) | ||
/// and pass in the `TransferRequest` so it gets the Receipt. | ||
/// Receipt is a Rule Witness, so there's no way to create | ||
/// it anywhere else but in this module. | ||
/// | ||
/// This example also illustrates that Rules can add Coin<SUI> | ||
/// to the balance of the TransferPolicy allowing creators to | ||
/// collect fees. | ||
public fun pay<T>( | ||
policy: &mut TransferPolicy<T>, | ||
request: &mut TransferRequest<T>, | ||
payment: Coin<SUI> | ||
) { | ||
policy::add_to_balance(Rule {}, policy, payment); | ||
policy::add_receipt(Rule {}, request); | ||
} | ||
} |
77 changes: 77 additions & 0 deletions
77
unit-five/example_projects/kiosk/sources/fixed_royalty_rule.move
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
// Copyright (c) Sui Foundation, Inc. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
// The code is modified from here https://github.com/MystenLabs/apps/blob/main/kiosk/sources/rules/royalty_rule.move | ||
|
||
module kiosk::fixed_royalty_rule { | ||
use sui::sui::SUI; | ||
use sui::coin::{Self, Coin}; | ||
use sui::transfer_policy::{ | ||
Self, | ||
TransferPolicy, | ||
TransferPolicyCap, | ||
TransferRequest | ||
}; | ||
|
||
/// The `amount_bp` passed is more than 100%. | ||
const EIncorrectArgument: u64 = 0; | ||
/// The `Coin` used for payment is not enough to cover the fee. | ||
const EInsufficientAmount: u64 = 1; | ||
|
||
/// Max value for the `amount_bp`. | ||
const MAX_BPS: u16 = 10_000; | ||
|
||
/// The Rule Witness to authorize the policy | ||
struct Rule has drop {} | ||
|
||
/// Configuration for the Rule | ||
struct Config has store, drop { | ||
/// Percentage of the transfer amount to be paid as royalty fee | ||
amount_bp: u16, | ||
/// This is used as royalty fee if the calculated fee is smaller than `min_amount` | ||
min_amount: u64, | ||
} | ||
|
||
/// Function that adds a Rule to the `TransferPolicy`. | ||
/// Requires `TransferPolicyCap` to make sure the rules are | ||
/// added only by the publisher of T. | ||
public fun add<T>( | ||
policy: &mut TransferPolicy<T>, | ||
cap: &TransferPolicyCap<T>, | ||
amount_bp: u16, | ||
min_amount: u64 | ||
|
||
) { | ||
assert!(amount_bp <= MAX_BPS, EIncorrectArgument); | ||
transfer_policy::add_rule(Rule {}, policy, cap, Config { amount_bp, min_amount }) | ||
} | ||
|
||
/// Buyer action: Pay the royalty fee for the transfer. | ||
public fun pay<T: key + store>( | ||
policy: &mut TransferPolicy<T>, | ||
request: &mut TransferRequest<T>, | ||
payment: Coin<SUI> | ||
) { | ||
let paid = transfer_policy::paid(request); | ||
let amount = fee_amount(policy, paid); | ||
|
||
assert!(coin::value(&payment) == amount, EInsufficientAmount); | ||
|
||
transfer_policy::add_to_balance(Rule {}, policy, payment); | ||
transfer_policy::add_receipt(Rule {}, request) | ||
} | ||
|
||
/// Helper function to calculate the amount to be paid for the transfer. | ||
/// Can be used dry-runned to estimate the fee amount based on the Kiosk listing price. | ||
public fun fee_amount<T: key + store>(policy: &TransferPolicy<T>, paid: u64): u64 { | ||
let config: &Config = transfer_policy::get_rule(Rule {}, policy); | ||
let amount = (((paid as u128) * (config.amount_bp as u128) / 10_000) as u64); | ||
|
||
// If the amount is less than the minimum, use the minimum | ||
if (amount < config.min_amount) { | ||
amount = config.min_amount | ||
}; | ||
|
||
amount | ||
} | ||
} |
Oops, something went wrong.