import * as $ from "@manahippo/move-to-ts"; import {AptosDataCache, AptosParserRepo, DummyCache, AptosLocalCache} from "@manahippo/move-to-ts"; import {U8, U64, U128} from "@manahippo/move-to-ts"; import {u8, u64, u128} from "@manahippo/move-to-ts"; import {TypeParamDeclType, FieldDeclType} from "@manahippo/move-to-ts"; import {AtomicTypeTag, StructTag, TypeTag, VectorTag, SimpleStructTag} from "@manahippo/move-to-ts"; import {OptionTransaction} from "@manahippo/move-to-ts"; import {HexString, AptosClient, AptosAccount, TxnBuilderTypes, Types} from "aptos"; import * as Error from "./error"; import * as Simple_map from "./simple_map"; import * as Vector from "./vector"; export const packageName = "AptosStdlib"; export const moduleAddress = new HexString("0x1"); export const moduleName = "pool_u64"; export const EINSUFFICIENT_SHARES : U64 = u64("4"); export const EPOOL_IS_NOT_EMPTY : U64 = u64("3"); export const EPOOL_TOTAL_COINS_OVERFLOW : U64 = u64("6"); export const EPOOL_TOTAL_SHARES_OVERFLOW : U64 = u64("7"); export const ESHAREHOLDER_NOT_FOUND : U64 = u64("1"); export const ESHAREHOLDER_SHARES_OVERFLOW : U64 = u64("5"); export const ETOO_MANY_SHAREHOLDERS : U64 = u64("2"); export const MAX_U64 : U64 = u64("18446744073709551615"); export class Pool { static moduleAddress = moduleAddress; static moduleName = moduleName; __app: $.AppType | null = null; static structName: string = "Pool"; static typeParameters: TypeParamDeclType[] = [ ]; static fields: FieldDeclType[] = [ { name: "shareholders_limit", typeTag: AtomicTypeTag.U64 }, { name: "total_coins", typeTag: AtomicTypeTag.U64 }, { name: "total_shares", typeTag: AtomicTypeTag.U64 }, { name: "shares", typeTag: new StructTag(new HexString("0x1"), "simple_map", "SimpleMap", [AtomicTypeTag.Address, AtomicTypeTag.U64]) }, { name: "shareholders", typeTag: new VectorTag(AtomicTypeTag.Address) }, { name: "scaling_factor", typeTag: AtomicTypeTag.U64 }]; shareholders_limit: U64; total_coins: U64; total_shares: U64; shares: Simple_map.SimpleMap; shareholders: HexString[]; scaling_factor: U64; constructor(proto: any, public typeTag: TypeTag) { this.shareholders_limit = proto['shareholders_limit'] as U64; this.total_coins = proto['total_coins'] as U64; this.total_shares = proto['total_shares'] as U64; this.shares = proto['shares'] as Simple_map.SimpleMap; this.shareholders = proto['shareholders'] as HexString[]; this.scaling_factor = proto['scaling_factor'] as U64; } static PoolParser(data:any, typeTag: TypeTag, repo: AptosParserRepo) : Pool { const proto = $.parseStructProto(data, typeTag, repo, Pool); return new Pool(proto, typeTag); } static getTag(): StructTag { return new StructTag(moduleAddress, moduleName, "Pool", []); } async loadFullState(app: $.AppType) { await this.shares.loadFullState(app); this.__app = app; } } export function add_shares_ ( pool: Pool, shareholder: HexString, new_shares: U64, $c: AptosDataCache, ): U64 { let temp$1, temp$2, temp$3, temp$4, current_shares, existing_shares; [temp$1, temp$2] = [pool, $.copy(shareholder)]; if (contains_(temp$1, temp$2, $c)) { existing_shares = Simple_map.borrow_mut_(pool.shares, shareholder, $c, [AtomicTypeTag.Address, AtomicTypeTag.U64]); current_shares = $.copy(existing_shares); if (!(($.copy(MAX_U64)).sub($.copy(current_shares))).ge($.copy(new_shares))) { throw $.abortCode(Error.invalid_argument_($.copy(ESHAREHOLDER_SHARES_OVERFLOW), $c)); } $.set(existing_shares, ($.copy(current_shares)).add($.copy(new_shares))); temp$4 = $.copy(existing_shares); } else{ if (($.copy(new_shares)).gt(u64("0"))) { if (!(Vector.length_(pool.shareholders, $c, [AtomicTypeTag.Address])).lt($.copy(pool.shareholders_limit))) { throw $.abortCode(Error.invalid_state_($.copy(ETOO_MANY_SHAREHOLDERS), $c)); } Vector.push_back_(pool.shareholders, $.copy(shareholder), $c, [AtomicTypeTag.Address]); Simple_map.add_(pool.shares, $.copy(shareholder), $.copy(new_shares), $c, [AtomicTypeTag.Address, AtomicTypeTag.U64]); temp$3 = $.copy(new_shares); } else{ temp$3 = $.copy(new_shares); } temp$4 = temp$3; } return temp$4; } export function amount_to_shares_ ( pool: Pool, coins_amount: U64, $c: AptosDataCache, ): U64 { return amount_to_shares_with_total_coins_(pool, $.copy(coins_amount), $.copy(pool.total_coins), $c); } export function amount_to_shares_with_total_coins_ ( pool: Pool, coins_amount: U64, total_coins: U64, $c: AptosDataCache, ): U64 { let temp$1, temp$2; if (($.copy(pool.total_coins)).eq((u64("0")))) { temp$1 = true; } else{ temp$1 = ($.copy(pool.total_shares)).eq((u64("0"))); } if (temp$1) { temp$2 = ($.copy(coins_amount)).mul($.copy(pool.scaling_factor)); } else{ temp$2 = multiply_then_divide_(pool, $.copy(coins_amount), $.copy(pool.total_shares), $.copy(total_coins), $c); } return temp$2; } export function balance_ ( pool: Pool, shareholder: HexString, $c: AptosDataCache, ): U64 { let num_shares; num_shares = shares_(pool, $.copy(shareholder), $c); return shares_to_amount_(pool, $.copy(num_shares), $c); } export function buy_in_ ( pool: Pool, shareholder: HexString, coins_amount: U64, $c: AptosDataCache, ): U64 { let temp$1, temp$2, new_shares; if (($.copy(coins_amount)).eq((u64("0")))) { return u64("0"); } else{ } [temp$1, temp$2] = [pool, $.copy(coins_amount)]; new_shares = amount_to_shares_(temp$1, temp$2, $c); if (!(($.copy(MAX_U64)).sub($.copy(pool.total_coins))).ge($.copy(coins_amount))) { throw $.abortCode(Error.invalid_argument_($.copy(EPOOL_TOTAL_COINS_OVERFLOW), $c)); } if (!(($.copy(MAX_U64)).sub($.copy(pool.total_shares))).ge($.copy(new_shares))) { throw $.abortCode(Error.invalid_argument_($.copy(EPOOL_TOTAL_COINS_OVERFLOW), $c)); } pool.total_coins = ($.copy(pool.total_coins)).add($.copy(coins_amount)); pool.total_shares = ($.copy(pool.total_shares)).add($.copy(new_shares)); add_shares_(pool, $.copy(shareholder), $.copy(new_shares), $c); return $.copy(new_shares); } export function contains_ ( pool: Pool, shareholder: HexString, $c: AptosDataCache, ): boolean { return Simple_map.contains_key_(pool.shares, shareholder, $c, [AtomicTypeTag.Address, AtomicTypeTag.U64]); } export function create_ ( shareholders_limit: U64, $c: AptosDataCache, ): Pool { return create_with_scaling_factor_($.copy(shareholders_limit), u64("1"), $c); } export function create_with_scaling_factor_ ( shareholders_limit: U64, scaling_factor: U64, $c: AptosDataCache, ): Pool { return new Pool({ shareholders_limit: $.copy(shareholders_limit), total_coins: u64("0"), total_shares: u64("0"), shares: Simple_map.create_($c, [AtomicTypeTag.Address, AtomicTypeTag.U64]), shareholders: Vector.empty_($c, [AtomicTypeTag.Address]), scaling_factor: $.copy(scaling_factor) }, new SimpleStructTag(Pool)); } export function deduct_shares_ ( pool: Pool, shareholder: HexString, num_shares: U64, $c: AptosDataCache, ): U64 { let temp$1, temp$2, temp$3, temp$4, existing_shares, remaining_shares, shareholder_index; [temp$1, temp$2] = [pool, $.copy(shareholder)]; if (!contains_(temp$1, temp$2, $c)) { throw $.abortCode(Error.invalid_argument_($.copy(ESHAREHOLDER_NOT_FOUND), $c)); } [temp$3, temp$4] = [pool, $.copy(shareholder)]; if (!(shares_(temp$3, temp$4, $c)).ge($.copy(num_shares))) { throw $.abortCode(Error.invalid_argument_($.copy(EINSUFFICIENT_SHARES), $c)); } existing_shares = Simple_map.borrow_mut_(pool.shares, shareholder, $c, [AtomicTypeTag.Address, AtomicTypeTag.U64]); $.set(existing_shares, ($.copy(existing_shares)).sub($.copy(num_shares))); remaining_shares = $.copy(existing_shares); if (($.copy(remaining_shares)).eq((u64("0")))) { [, shareholder_index] = Vector.index_of_(pool.shareholders, shareholder, $c, [AtomicTypeTag.Address]); Vector.remove_(pool.shareholders, $.copy(shareholder_index), $c, [AtomicTypeTag.Address]); Simple_map.remove_(pool.shares, shareholder, $c, [AtomicTypeTag.Address, AtomicTypeTag.U64]); } else{ } return $.copy(remaining_shares); } export function destroy_empty_ ( pool: Pool, $c: AptosDataCache, ): void { if (!($.copy(pool.total_coins)).eq((u64("0")))) { throw $.abortCode(Error.invalid_state_($.copy(EPOOL_IS_NOT_EMPTY), $c)); } pool; return; } export function multiply_then_divide_ ( _pool: Pool, x: U64, y: U64, z: U64, $c: AptosDataCache, ): U64 { let result; result = ((to_u128_($.copy(x), $c)).mul(to_u128_($.copy(y), $c))).div(to_u128_($.copy(z), $c)); return u64($.copy(result)); } export function redeem_shares_ ( pool: Pool, shareholder: HexString, shares_to_redeem: U64, $c: AptosDataCache, ): U64 { let temp$1, temp$2, temp$3, temp$4, temp$5, temp$6, redeemed_coins; [temp$1, temp$2] = [pool, $.copy(shareholder)]; if (!contains_(temp$1, temp$2, $c)) { throw $.abortCode(Error.invalid_argument_($.copy(ESHAREHOLDER_NOT_FOUND), $c)); } [temp$3, temp$4] = [pool, $.copy(shareholder)]; if (!(shares_(temp$3, temp$4, $c)).ge($.copy(shares_to_redeem))) { throw $.abortCode(Error.invalid_argument_($.copy(EINSUFFICIENT_SHARES), $c)); } if (($.copy(shares_to_redeem)).eq((u64("0")))) { return u64("0"); } else{ } [temp$5, temp$6] = [pool, $.copy(shares_to_redeem)]; redeemed_coins = shares_to_amount_(temp$5, temp$6, $c); pool.total_coins = ($.copy(pool.total_coins)).sub($.copy(redeemed_coins)); pool.total_shares = ($.copy(pool.total_shares)).sub($.copy(shares_to_redeem)); deduct_shares_(pool, $.copy(shareholder), $.copy(shares_to_redeem), $c); return $.copy(redeemed_coins); } export function shareholders_ ( pool: Pool, $c: AptosDataCache, ): HexString[] { return $.copy(pool.shareholders); } export function shareholders_count_ ( pool: Pool, $c: AptosDataCache, ): U64 { return Vector.length_(pool.shareholders, $c, [AtomicTypeTag.Address]); } export function shares_ ( pool: Pool, shareholder: HexString, $c: AptosDataCache, ): U64 { let temp$1; if (contains_(pool, $.copy(shareholder), $c)) { temp$1 = $.copy(Simple_map.borrow_(pool.shares, shareholder, $c, [AtomicTypeTag.Address, AtomicTypeTag.U64])); } else{ temp$1 = u64("0"); } return temp$1; } export function shares_to_amount_ ( pool: Pool, shares: U64, $c: AptosDataCache, ): U64 { return shares_to_amount_with_total_coins_(pool, $.copy(shares), $.copy(pool.total_coins), $c); } export function shares_to_amount_with_total_coins_ ( pool: Pool, shares: U64, total_coins: U64, $c: AptosDataCache, ): U64 { let temp$1, temp$2; if (($.copy(pool.total_coins)).eq((u64("0")))) { temp$1 = true; } else{ temp$1 = ($.copy(pool.total_shares)).eq((u64("0"))); } if (temp$1) { temp$2 = u64("0"); } else{ temp$2 = multiply_then_divide_(pool, $.copy(shares), $.copy(total_coins), $.copy(pool.total_shares), $c); } return temp$2; } export function to_u128_ ( num: U64, $c: AptosDataCache, ): U128 { return u128($.copy(num)); } export function total_coins_ ( pool: Pool, $c: AptosDataCache, ): U64 { return $.copy(pool.total_coins); } export function total_shares_ ( pool: Pool, $c: AptosDataCache, ): U64 { return $.copy(pool.total_shares); } export function transfer_shares_ ( pool: Pool, shareholder_1: HexString, shareholder_2: HexString, shares_to_transfer: U64, $c: AptosDataCache, ): void { let temp$1, temp$2, temp$3, temp$4; [temp$1, temp$2] = [pool, $.copy(shareholder_1)]; if (!contains_(temp$1, temp$2, $c)) { throw $.abortCode(Error.invalid_argument_($.copy(ESHAREHOLDER_NOT_FOUND), $c)); } [temp$3, temp$4] = [pool, $.copy(shareholder_1)]; if (!(shares_(temp$3, temp$4, $c)).ge($.copy(shares_to_transfer))) { throw $.abortCode(Error.invalid_argument_($.copy(EINSUFFICIENT_SHARES), $c)); } if (($.copy(shares_to_transfer)).eq((u64("0")))) { return; } else{ } deduct_shares_(pool, $.copy(shareholder_1), $.copy(shares_to_transfer), $c); add_shares_(pool, $.copy(shareholder_2), $.copy(shares_to_transfer), $c); return; } export function update_total_coins_ ( pool: Pool, new_total_coins: U64, $c: AptosDataCache, ): void { pool.total_coins = $.copy(new_total_coins); return; } export function loadParsers(repo: AptosParserRepo) { repo.addParser("0x1::pool_u64::Pool", Pool.PoolParser); } export class App { constructor( public client: AptosClient, public repo: AptosParserRepo, public cache: AptosLocalCache, ) { } get moduleAddress() {{ return moduleAddress; }} get moduleName() {{ return moduleName; }} get Pool() { return Pool; } }