Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions contracts/flash_loan_provider/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "flash-loan-provider"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
soroban-sdk = "28.0.0"

[dev-dependencies]
soroban-sdk = { version = "28.0.0", features = ["testutils"] }
42 changes: 42 additions & 0 deletions contracts/flash_loan_provider/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#![no_std]

use soroban_sdk::{contract, contracterror, contractimpl, panic_with_error, Address, Env, token};

#[contracterror]
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum FlashLoanError {
InvalidAmount = 1,
NotRepaid = 2,
AlreadyInitialized = 3,
NotInitialized = 4,
}

#[contract]
pub struct FlashLoanProvider;

#[contractimpl]
impl FlashLoanProvider {
pub fn initialize(env: Env, admin: Address, token: Address, fee_bps: i128) {
if env.storage().instance().has(&("admin")) {
panic_with_error!(&env, FlashLoanError::AlreadyInitialized);
}
env.storage().instance().set(&("admin"), &admin);
env.storage().instance().set(&("token"), &token);
env.storage().instance().set(&("fee_bps"), &fee_bps);
}

pub fn flash_loan(env: Env, borrower: Address, amount: i128) -> i128 {
if amount <= 0 {
panic_with_error!(&env, FlashLoanError::InvalidAmount);
}
let token_addr: Address = env.storage().instance().get(&("token")).unwrap();
let fee_bps: i128 = env.storage().instance().get(&("fee_bps")).unwrap_or(10);
let token = token::Client::new(&env, &token_addr);
let contract_addr = env.current_contract_address();
token.transfer(&contract_addr, &borrower, &amount);
let fee = (amount * fee_bps) / 10_000;
let repay = amount + fee;
token.transfer(&borrower, &contract_addr, &repay);
repay
}
}
13 changes: 13 additions & 0 deletions contracts/yield_farming/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "yield-farming"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

[dependencies]
soroban-sdk = "28.0.0"

[dev-dependencies]
soroban-sdk = { version = "28.0.0", features = ["testutils"] }
31 changes: 31 additions & 0 deletions contracts/yield_farming/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#![no_std]

use soroban_sdk::{contract, contractimpl, Address, Env, token};

#[contract]
pub struct YieldFarmingPool;

#[contractimpl]
impl YieldFarmingPool {
pub fn initialize(env: Env, admin: Address, staking_token: Address, reward_token: Address, reward_rate: i128) {
env.storage().instance().set(&("admin"), &admin);
env.storage().instance().set(&("staking_token"), &staking_token);
env.storage().instance().set(&("reward_token"), &reward_token);
env.storage().instance().set(&("reward_rate"), &reward_rate);
env.storage().instance().set(&("total_staked"), &0i128);
}

pub fn stake(env: Env, user: Address, amount: i128) {
let staking_token_addr: Address = env.storage().instance().get(&("staking_token")).unwrap();
let staking_token = token::Client::new(&env, &staking_token_addr);
staking_token.transfer(&user, &env.current_contract_address(), &amount);
let total: i128 = env.storage().instance().get(&("total_staked")).unwrap_or(0);
env.storage().instance().set(&("total_staked"), &(total + amount));
}

pub fn get_reward_per_token(env: Env) -> i128 {
let total: i128 = env.storage().instance().get(&("total_staked")).unwrap_or(0);
let rate: i128 = env.storage().instance().get(&("reward_rate")).unwrap_or(1);
if total == 0 { 0 } else { rate * 1000 / total }
}
}
53 changes: 53 additions & 0 deletions frontend/src/components/WasmDecompilerInspector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"use client";

import { useState } from "react";

export function WasmDecompilerInspector() {
const [file, setFile] = useState<File | null>(null);
const [disassembly, setDisassembly] = useState<string>("");
const [analyzing, setAnalyzing] = useState(false);

const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files?.[0]) {
setFile(e.target.files[0]);
}
};

const analyze = async () => {
if (!file) return;
setAnalyzing(true);
try {
// Mock disassembly - would use actual WASM decompiler
const mockDisasm = [
"00000000: 0061 736d 0100 0000 0106 017f 027f 037f .asm............",
"00000010: 0130 0000 0000 0201 0444 4d45 4d4f 0003 .0.......DMEMO..",
"00000020: 0001 0004 0001 0000 0005 0301 0001 0006 ................",
"00000030: 1501 027f 0080 0080 8000 000b 0701 000a ................",
].join("\n");
setDisassembly(mockDisasm);
} finally {
setAnalyzing(false);
}
};

return (
<div className="p-4 border rounded-lg">
<h2 className="text-xl font-semibold mb-4">WASM Decompiler & Disassembly Inspector</h2>
<div className="space-y-3">
<input type="file" accept=".wasm" onChange={handleFileChange} className="block w-full" />
<button
onClick={analyze}
disabled={!file || analyzing}
className="px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 disabled:opacity-50"
>
{analyzing ? "Analyzing..." : "Analyze WASM"}
</button>
</div>
{disassembly && (
<pre className="mt-4 p-3 bg-gray-900 text-green-400 text-xs overflow-auto rounded max-h-96">
{disassembly}
</pre>
)}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { render, screen } from "@testing-library/react";
import { WasmDecompilerInspector } from "../WasmDecompilerInspector";

describe("WasmDecompilerInspector", () => {
it("renders decompiler interface", () => {
render(<WasmDecompilerInspector />);
expect(screen.getByText(/WASM Decompiler/i)).toBeInTheDocument();
});
});
Loading