Skip to content

Commit

Permalink
treasury update
Browse files Browse the repository at this point in the history
  • Loading branch information
dangell7 committed Oct 17, 2024
1 parent 6ded6d9 commit 40fed20
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 49 deletions.
71 changes: 22 additions & 49 deletions contracts-c/treasury/genesis_mint.c
Original file line number Diff line number Diff line change
@@ -1,36 +1,25 @@
#include "hookapi.h"

#define DONE(x)\
accept(SVAR(x),(uint32_t)__LINE__);

#define NOPE(x)\
{\
return rollback((x), sizeof(x), __LINE__);\
}

#define sfGenesisMints ((15U << 16U) + 96U)
#define sfGenesisMint ((14U << 16U) + 96U)
#define ttGENESIS_MINT 96U

// clang-format off
uint8_t txn[238] =
{
/* size,upto */
/* 3, 0, tt = Payment */ 0x12U, 0x00U, 0x00U,
/* 5, 3, flags */ 0x22U, 0x00U, 0x00U, 0x00U, 0x00U,
/* 5, 8, sequence */ 0x24U, 0x00U, 0x00U, 0x00U, 0x00U,
/* 6, 13, firstledgersequence */ 0x20U, 0x1AU, 0x00U, 0x00U, 0x00U, 0x00U,
/* 6, 19, lastledgersequence */ 0x20U, 0x1BU, 0x00U, 0x00U, 0x00U, 0x00U,
/* 9, 25, amount */ 0x61U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U,
/* 9, 34, fee */ 0x68U, 0x40U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
/* 35, 43, signingpubkey */ 0x73U, 0x21U, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* 22, 78, account */ 0x81U, 0x14U, 0x88U, 0x59U, 0x00U, 0x4AU, 0xA9U, 0xEEU, 0xDCU, 0x00U, 0xB9U, 0xBDU, 0x5FU, 0xA0U, 0x9AU, 0xAEU, 0x43U, 0x25U, 0x52U, 0xECU, 0x84U, 0x3DU,
/* 22, 100, destination */ 0x83U, 0x14U, 0x88U, 0x58U, 0xFDU, 0x4DU, 0x78U, 0xCEU, 0x5EU, 0x97U, 0x2CU, 0x8CU, 0x1EU, 0x63U, 0xD5U, 0x1BU, 0x83U, 0x4FU, 0xF3U, 0x6FU, 0x14U, 0x11U,
/* 116, 122 emit details */
/* 0, 238 */
/* 3, 0, tt = Payment */ 0x12U, 0x00U, 0x00U,
/* 5, 3, flags */ 0x22U, 0x00U, 0x00U, 0x00U, 0x00U,
/* 5, 8, sequence */ 0x24U, 0x00U, 0x00U, 0x00U, 0x00U,
/* 6, 13, firstledgersequence */ 0x20U, 0x1AU, 0x00U, 0x00U, 0x00U, 0x00U,
/* 6, 19, lastledgersequence */ 0x20U, 0x1BU, 0x00U, 0x00U, 0x00U, 0x00U,
/* 9, 25, amount */ 0x61U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U, 0x99U,
/* 9, 34, fee */ 0x68U, 0x40U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
/* 35, 43, signingpubkey */ 0x73U, 0x21U, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* 22, 78, account */ 0x81U, 0x14U, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* 22, 100, destination */ 0x83U, 0x14U, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/* 116, 122 emit details */
/* 0, 238 */
};


#define FLS_OUT (txn + 15U)
#define LLS_OUT (txn + 21U)
#define FEE_OUT (txn + 35U)
Expand All @@ -41,18 +30,11 @@ uint8_t txn[238] =

int64_t hook(uint32_t reserved)
{
_g(1,1);

hook_account(ACC_OUT, 20);

hook_param(DEST_OUT, 20, "DST", 3);

int64_t tt = otxn_type();
if (tt != ttGENESIS_MINT)
DONE("genesis_mint.c: Pass Invalid Transaction Type.");
if(hook_param(DEST_OUT, 20, "D", 1) != 20)
rollback(SBUF("Genesis Mint: Destination Account not set as Hook parameter"), 1);

otxn_slot(1);

slot_subfield(1, sfGenesisMints, 1);
slot_subarray(1, 0, 1);
slot_subfield(1, sfGenesisMint, 1);
Expand All @@ -61,32 +43,24 @@ int64_t hook(uint32_t reserved)
int64_t txn_amount = slot_float(2);

uint8_t mint_dest[20];
slot_subfield(1, sfDestination, 3);
slot(SBUF(mint_dest), 3);

if (BUFFER_EQUAL_20(DEST_OUT, mint_dest))
NOPE("genesis_mint.c: Invalid Mint Destination.");
slot_subfield(1, sfDestination, 1);
slot(SBUF(mint_dest), 1);

// if(slot_type(2, 1) != 0)
// NOPE("genesis_mint.c: Invalid Issued Currency.");
if (!BUFFER_EQUAL_20(ACC_OUT, mint_dest))
rollback(SBUF("Genesis mint: Invalid Mint Destination."), 2);

// TXN: PREPARE: Init
etxn_reserve(1);

// TXN PREPARE: FirstLedgerSequence
uint32_t fls = (uint32_t)ledger_seq() + 1;
*((uint32_t *)(FLS_OUT)) = FLIP_ENDIAN(fls);

// TXN PREPARE: LastLedgerSequense
uint32_t lls = fls + 4;
*((uint32_t *)(LLS_OUT)) = FLIP_ENDIAN(lls);

// TXN PREPARE: Emit Metadata

etxn_details(EMIT_OUT, 116U);

// TXN PREPARE: Amount
uint64_t drops = float_int(txn_amount, 6, 1);
TRACEVAR(drops);
uint8_t *b = AMOUNT_OUT + 1;
*b++ = 0b01000000 + ((drops >> 56) & 0b00111111);
*b++ = (drops >> 48) & 0xFFU;
Expand All @@ -111,12 +85,11 @@ int64_t hook(uint32_t reserved)
*b++ = (fee >> 0) & 0xFFU;
}

TRACEHEX(txn);

uint8_t emithash[32];
if(emit(SBUF(emithash), SBUF(txn)) != 32)
rollback(SBUF("genesis_mint.c: Failed To Emit."), 9);
rollback(SBUF("Genesis Mint: Failed To Emit."), 3);

DONE("genesis_mint.c: Passing ClaimReward.");
accept(SBUF("Genesis Mint: Passing ClaimReward."), 4);
_g(1,1);
return 0;
}
61 changes: 61 additions & 0 deletions contracts-c/treasury/treasury.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "hookapi.h"

#define OTXN_AMT_TO_XFL(buf) float_set(-6, (AMOUNT_TO_DROPS(buf)))

int64_t hook(uint32_t reserved)
{
// ROLLBACK: Because not setting this would be a misconfiguration
uint64_t limit_amt;
if(hook_param(SVAR(limit_amt), "A", 1) != 8)
rollback(SBUF("Treasury: Misconfigured. Amount 'A' not set as Hook parameter"), 1);

// ROLLBACK: Because not setting this would be a misconfiguration
int32_t limit_ledger;
if(hook_param(SVAR(limit_ledger), "L", 1) != 4)
rollback(SBUF("Treasury: Misconfigured. Ledger limit 'L' not set as Hook parameter"), 2);

uint8_t otxn_account[20];
otxn_field(SBUF(otxn_account), sfAccount);

uint8_t account[20];
hook_account(SBUF(otxn_account));
if(!BUFFER_EQUAL_20(otxn_account, account))
accept(SBUF("Treasury: Incoming Transaction."), 7);

int64_t type = otxn_type();
if (type == ttCLAIM_REWARD)
accept(SBUF("Treasury: ClaimReward Successful."), 4);

// MUST ROLLBACK
uint8_t amount_buf[8];
if(otxn_field(amount_buf, 8, sfAmount) != 8)
rollback(SBUF("Treasury: Non XAH currency payments are forbidden."), 6);

int32_t last_release = 0;
state(SVAR(last_release), "LAST", 4);

int32_t current_ledger = ledger_seq();

// MUST ROLLBACK
if ((last_release + limit_ledger) > current_ledger)
rollback(SBUF("Treasury: You need to wait longer to withdraw."), 8);

if (last_release == 0 && type == ttSET_HOOK)
accept(SBUF("Treasury: Hook Set Successfully."), 13);

// MUST ROLLBACK
if (type != ttPAYMENT)
rollback(SBUF("Treasury: Only ClaimReward and Payment txns are allowed."), 5);

// MUST ROLLBACK
int64_t amount_xfl = OTXN_AMT_TO_XFL(amount_buf);
if(float_compare(amount_xfl, limit_amt, COMPARE_GREATER) == 1)
rollback(SBUF("Treasury: Outgoing transaction exceeds the limit set by you."), 9);

if (state_set(SVAR(current_ledger), "LAST", 4) != 4)
rollback(SBUF("Treasury: Could not update state entry, bailing."), 11);

accept(SBUF("Treasury: Released successfully."), 12);
_g(1,1);
return 0;
}
104 changes: 104 additions & 0 deletions test/integration-c/treasury/genesisMint.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// xrpl
import {
Client,
Wallet,
AccountSetAsfFlags,
SetHookFlags,
TransactionMetadata,
ClaimReward,
} from '@transia/xrpl'
// xrpl-helpers
import { accountSet } from '@transia/hooks-toolkit/dist/npm/src/libs/xrpl-helpers'
// src
import {
Xrpld,
SetHookParams,
setHooksV3,
createHookPayload,
iHookParamEntry,
iHookParamName,
iHookParamValue,
ExecutionUtility,
} from '@transia/hooks-toolkit'
import { xrpAddressToHex } from '@transia/hooks-toolkit/dist/npm/src/libs/binary-models'

const serverUrl = 'wss://xahau-test.net'
const hookSeed = 'snnf9az3KyNUfVRtER43grtixDrRy'
const destSeed = 'snDnCTwy5k2UdFq7fYnWxiXeEbdfJ'

describe('treasury', () => {
let client: Client

beforeAll(async () => {
client = new Client(serverUrl)
await client.connect()
client.networkID = await client.getNetworkID()
const hookWallet = Wallet.fromSeed(hookSeed)
const destWallet = Wallet.fromSeed(destSeed)

accountSet(client, hookWallet, AccountSetAsfFlags.asfTshCollect)
const hookParam1 = new iHookParamEntry(
new iHookParamName('DST'),
new iHookParamValue(xrpAddressToHex(destWallet.classicAddress), true)
)
const acct1hook1 = createHookPayload({
version: 0,
createFile: 'genesis_mint',
namespace: 'treasury',
flags: SetHookFlags.hsfCollect + SetHookFlags.hsfOverride,
hookOnArray: ['GenesisMint'],
hookParams: [hookParam1.toXrpl()],
})
await setHooksV3({
client: client,
seed: hookWallet.seed,
hooks: [{ Hook: acct1hook1 }],
} as SetHookParams)
})

afterAll(async () => {
client.disconnect()
})

it('treasury - success', async () => {
client.networkID = await client.getNetworkID()
const hookWallet = Wallet.fromSeed(hookSeed)

// Opt In ClaimReward
const optInTx: ClaimReward = {
TransactionType: 'ClaimReward',
Account: hookWallet.classicAddress,
Issuer: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
}
await Xrpld.submit(client, {
wallet: hookWallet,
tx: optInTx,
debugStream: true,
})

// Wait 100 Seconds
await new Promise((resolve) => setTimeout(resolve, 100000)) // await

// ClaimReward
const claimTx: ClaimReward = {
TransactionType: 'ClaimReward',
Account: hookWallet.classicAddress,
Issuer: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
}
const result = await Xrpld.submit(client, {
wallet: hookWallet,
tx: claimTx,
debugStream: true,
})

const hookExecutions = await ExecutionUtility.getHookExecutionsFromMeta(
client,
result.meta as TransactionMetadata
)
console.log(hookExecutions)

expect(hookExecutions.executions[0].HookReturnString).toMatch(
'auction_start.c: Tx emitted success'
)
})
})

0 comments on commit 40fed20

Please sign in to comment.