diff --git a/Cargo.lock b/Cargo.lock index f29d2d42e..bd2ed74d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1802,12 +1802,12 @@ name = "hello-solana-asm-program" version = "0.1.0" dependencies = [ "litesvm", - "solana-instruction 3.0.0", + "solana-instruction 3.3.0", "solana-keypair", "solana-native-token 3.0.0", "solana-pubkey 3.0.0", "solana-system-interface 2.0.0", - "solana-transaction", + "solana-transaction 3.1.0", ] [[package]] diff --git a/basics/account-data/README.md b/basics/account-data/README.md new file mode 100644 index 000000000..bfa1c74d3 --- /dev/null +++ b/basics/account-data/README.md @@ -0,0 +1,22 @@ +# Account Data + +:package: We're going to store data in a Solana account. :memo: + +Solana accounts are used to store persistent state. This means that the data stays on the blockchain until the account is closed. + +In this example, we demonstrate how to: +1. **Define a data structure**: We create an `AddressInfo` struct to store a name, house number, street, and city. +2. **Calculate required space**: We determine how much memory (bytes) the account needs to store our structure. +3. **Initialize the account**: We allocate the space and write the initial data. + +### Frameworks covered: +- **Anchor**: Uses `#[account]` and `#[derive(InitSpace)]` to automate space calculation. +- **Native**: Manually calculates space and uses `Borsh` for serialization. +- **Pinocchio**: A lightweight approach to account data management. + +Each implementation shows how to handle fixed-size data and strings with maximum lengths. + +### Links: +- [Solana Docs - Accounts](https://docs.solana.com/developing/programming-model/accounts) +- [Anchor Docs - Space Reference](https://www.anchor-lang.com/docs/space) +- [Borsh Specification](https://borsh.io/) diff --git a/tokens/token-swap/anchor/programs/token-swap/src/instructions/deposit_liquidity.rs b/tokens/token-swap/anchor/programs/token-swap/src/instructions/deposit_liquidity.rs index 555e1fdfa..88ca8ce69 100644 --- a/tokens/token-swap/anchor/programs/token-swap/src/instructions/deposit_liquidity.rs +++ b/tokens/token-swap/anchor/programs/token-swap/src/instructions/deposit_liquidity.rs @@ -38,13 +38,13 @@ pub fn deposit_liquidity( (amount_a, amount_b) } else { let ratio = I64F64::from_num(pool_a.amount) - .checked_mul(I64F64::from_num(pool_b.amount)) - .unwrap(); + .checked_div(I64F64::from_num(pool_b.amount)) + .ok_or(TutorialError::DepositTooSmall)?; if pool_a.amount > pool_b.amount { ( I64F64::from_num(amount_b) .checked_mul(ratio) - .unwrap() + .ok_or(TutorialError::DepositTooSmall)? .to_num::(), amount_b, ) diff --git a/tokens/token-swap/anchor/programs/token-swap/src/lib.rs b/tokens/token-swap/anchor/programs/token-swap/src/lib.rs index d14e89724..e2f36af3d 100644 --- a/tokens/token-swap/anchor/programs/token-swap/src/lib.rs +++ b/tokens/token-swap/anchor/programs/token-swap/src/lib.rs @@ -6,7 +6,7 @@ mod instructions; mod state; // Set the correct key here -declare_id!("AsGVFxWqEn8icRBFQApxJe68x3r9zvfSbmiEzYFATGYn"); +declare_id!("14EcVFUfkQUpMFH4DSK3TZZiB8di7XzCJsuVpV12YEa8"); #[program] pub mod swap_example { diff --git a/tokens/token-swap/anchor/tests/deposit-liquidity.ts b/tokens/token-swap/anchor/tests/deposit-liquidity.ts index edf313ece..61fdbfdcd 100644 --- a/tokens/token-swap/anchor/tests/deposit-liquidity.ts +++ b/tokens/token-swap/anchor/tests/deposit-liquidity.ts @@ -43,9 +43,9 @@ describe("Deposit liquidity", () => { .rpc(); }); - it("Deposit equal amounts", async () => { + it("Deposit liquidity", async () => { await program.methods - .depositLiquidity(values.depositAmountA, values.depositAmountA) + .depositLiquidity(values.depositAmountA, values.depositAmountB) .accounts({ pool: values.poolKey, poolAuthority: values.poolAuthority, @@ -62,13 +62,19 @@ describe("Deposit liquidity", () => { .signers([values.admin]) .rpc({ skipPreflight: true }); + // liquidity = sqrt(amount_a * amount_b) - minimumLiquidity + const expectedLiquidity = + Math.floor(Math.sqrt(values.depositAmountA.toNumber() * values.depositAmountB.toNumber())) - + values.minimumLiquidity.toNumber(); + const depositTokenAccountLiquditiy = await connection.getTokenAccountBalance(values.liquidityAccount); - expect(depositTokenAccountLiquditiy.value.amount).to.equal( - values.depositAmountA.sub(values.minimumLiquidity).toString(), - ); + expect(depositTokenAccountLiquditiy.value.amount).to.equal(expectedLiquidity.toString()); + const depositTokenAccountA = await connection.getTokenAccountBalance(values.holderAccountA); expect(depositTokenAccountA.value.amount).to.equal(values.defaultSupply.sub(values.depositAmountA).toString()); + const depositTokenAccountB = await connection.getTokenAccountBalance(values.holderAccountB); - expect(depositTokenAccountB.value.amount).to.equal(values.defaultSupply.sub(values.depositAmountA).toString()); + // Token B deducted = depositAmountB, not depositAmountA + expect(depositTokenAccountB.value.amount).to.equal(values.defaultSupply.sub(values.depositAmountB).toString()); }); });