cryptnox-pos 1.0.0
Standalone USDC payment terminal firmware (ESP32 + Cryptnox smart card)
Loading...
Searching...
No Matches
money.h File Reference

The sale's arithmetic: keypad cents, base units, wei, fees, calldata. More...

#include <inttypes.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "CW_Utils.h"
#include "eth_addr.h"
#include "settings.h"
Include dependency graph for money.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define AMOUNT_CENTS_MAX   999999ULL /* 9999.99 */
#define AMOUNT_CENTS_MAX_NATIVE   (POS_AMOUNT_UNITS_MAX_NATIVE / 10000ULL)
#define ABI_SELECTOR_LEN   4U /* transfer(address,uint256) selector */
#define ABI_WORD_LEN   32U /* one ABI-encoded argument word */
#define USDC_CALLDATA_LEN   (ABI_SELECTOR_LEN + (2U * ABI_WORD_LEN)) /* 68 */
#define ABI_TO_OFFSET   (ABI_SELECTOR_LEN + (ABI_WORD_LEN - ETH_ADDR_LEN))

Enumerations

enum  evm_funds_t { EVM_FUNDS_OK = 0 , EVM_FUNDS_SHORT_GAS , EVM_FUNDS_SHORT_VALUE , EVM_FUNDS_UNKNOWN }
 What the pre-flight balance check concluded. More...

Functions

static uint64_t amount_cents_cap (bool native)
 Ceiling on what the keypad will accept, in cents.
static uint64_t amount_key_digit (uint64_t cents, unsigned digit, uint64_t cap)
 A digit shifted in from the right; refused whole if it passes cap.
static uint64_t amount_key_00 (uint64_t cents, uint64_t cap)
 The "00" key: two zeroes shifted in, clamped to cap.
static uint64_t amount_key_back (uint64_t cents)
 The backspace key: the last digit dropped.
static uint64_t amount_cents_to_units (uint64_t cents)
 Keypad cents to 6-decimal base units.
static void amount_format (uint64_t units, char *out, size_t n)
 "12.50": 6-decimal base units to two places, truncated.
static bool evm_units_to_wei (uint64_t units, uint64_t *wei)
 6-decimal keypad units -> wei, for the 18-decimal coins only.
static void evm_fees_from_gwei (uint32_t max_gwei, uint32_t prio_gwei, bool polygon, uint32_t floor_gwei, uint64_t *max_fee, uint64_t *prio_fee)
 The EIP-1559 fees one EVM sale will offer, in wei per gas, from the operator's Gwei settings.
static evm_funds_t evm_funds_check (bool native, uint64_t have_wei, uint64_t gas_cost, uint64_t units)
 Can have_wei pay for this sale?
static void fmt_coin (char *out, size_t n, uint64_t v, unsigned dec, const char *coin)
 "0.0013 ETH": v base units of a dec-decimal coin, to six places, rounded UP — it is a ceiling, and rounding down would understate it.
static void build_usdc_calldata (uint8_t out[USDC_CALLDATA_LEN], const uint8_t to[ETH_ADDR_LEN], uint64_t amount)
 Build the 68-byte ABI-encoded calldata for a USDC transfer call.

Variables

static const uint8_t TRANSFER_SELECTOR [4] = { 0xa9U, 0x05U, 0x9cU, 0xbbU }

Detailed Description

The sale's arithmetic: keypad cents, base units, wei, fees, calldata.

Header-only and free of ESP-IDF dependencies on purpose, like form_parse.h. Every number the customer is charged passes through these few lines, and a mistake in them is silent — a wrapped multiply signs a value nobody entered, a byte out of place in the calldata pays somebody else. So they live where a host test can hold them against vectors from an independent signer (tests/units/test_money.cpp, tools/gen_kat_vectors.py), rather than as statics in main.cpp and ui.cpp where nothing could reach them.

Definition in file money.h.

Macro Definition Documentation

◆ ABI_SELECTOR_LEN

#define ABI_SELECTOR_LEN   4U /* transfer(address,uint256) selector */

Definition at line 197 of file money.h.

Referenced by build_usdc_calldata().

◆ ABI_TO_OFFSET

#define ABI_TO_OFFSET   (ABI_SELECTOR_LEN + (ABI_WORD_LEN - ETH_ADDR_LEN))

Definition at line 200 of file money.h.

Referenced by build_usdc_calldata().

◆ ABI_WORD_LEN

#define ABI_WORD_LEN   32U /* one ABI-encoded argument word */

Definition at line 198 of file money.h.

◆ AMOUNT_CENTS_MAX

#define AMOUNT_CENTS_MAX   999999ULL /* 9999.99 */

Definition at line 40 of file money.h.

Referenced by amount_cents_cap().

◆ AMOUNT_CENTS_MAX_NATIVE

#define AMOUNT_CENTS_MAX_NATIVE   (POS_AMOUNT_UNITS_MAX_NATIVE / 10000ULL)

Definition at line 42 of file money.h.

Referenced by amount_cents_cap().

◆ USDC_CALLDATA_LEN

#define USDC_CALLDATA_LEN   (ABI_SELECTOR_LEN + (2U * ABI_WORD_LEN)) /* 68 */

Definition at line 199 of file money.h.

Referenced by build_usdc_calldata(), and sign_and_broadcast().

Enumeration Type Documentation

◆ evm_funds_t

What the pre-flight balance check concluded.

Enumerator
EVM_FUNDS_OK 

Covered (for a token: the gas is).

EVM_FUNDS_SHORT_GAS 

Not even the network fee.

EVM_FUNDS_SHORT_VALUE 

The fee, but not the fee plus the amount.

EVM_FUNDS_UNKNOWN 

Amount past the native cap: not ours to say.

Definition at line 144 of file money.h.

Function Documentation

◆ amount_cents_cap()

uint64_t amount_cents_cap ( bool native)
inlinestatic

Ceiling on what the keypad will accept, in cents.

ETH and POL are 18-decimal and the signed value is a uint64 of wei, so a sale stops at 18.44 of either (see POS_AMOUNT_UNITS_MAX_NATIVE).

Parameters
[in]nativetrue for an EVM network's own coin (ETH, POL).

Definition at line 52 of file money.h.

References AMOUNT_CENTS_MAX, and AMOUNT_CENTS_MAX_NATIVE.

Referenced by amount_cents_max().

◆ amount_cents_to_units()

uint64_t amount_cents_to_units ( uint64_t cents)
inlinestatic

Keypad cents to 6-decimal base units.

Definition at line 78 of file money.h.

Referenced by amount_update_display().

◆ amount_format()

void amount_format ( uint64_t units,
char * out,
size_t n )
inlinestatic

"12.50": 6-decimal base units to two places, truncated.

Definition at line 84 of file money.h.

◆ amount_key_00()

uint64_t amount_key_00 ( uint64_t cents,
uint64_t cap )
inlinestatic

The "00" key: two zeroes shifted in, clamped to cap.

Definition at line 65 of file money.h.

Referenced by amount_kbd_cb().

◆ amount_key_back()

uint64_t amount_key_back ( uint64_t cents)
inlinestatic

The backspace key: the last digit dropped.

Definition at line 72 of file money.h.

Referenced by amount_kbd_cb().

◆ amount_key_digit()

uint64_t amount_key_digit ( uint64_t cents,
unsigned digit,
uint64_t cap )
inlinestatic

A digit shifted in from the right; refused whole if it passes cap.

Definition at line 58 of file money.h.

Referenced by amount_kbd_cb().

◆ build_usdc_calldata()

void build_usdc_calldata ( uint8_t out[USDC_CALLDATA_LEN],
const uint8_t to[ETH_ADDR_LEN],
uint64_t amount )
inlinestatic

Build the 68-byte ABI-encoded calldata for a USDC transfer call.

Encodes the ERC-20 transfer(address,uint256) selector followed by the ABI-encoded arguments:

selector(4) | zeroes(12) | to(20) | zeroes(24) | amount_be(8)
Parameters
[out]outOutput buffer of USDC_CALLDATA_LEN bytes.
[in]toRecipient address, ETH_ADDR_LEN bytes (already parsed/validated).
[in]amountTransfer amount in USDC base units (6 decimals).

Definition at line 216 of file money.h.

References ABI_SELECTOR_LEN, ABI_TO_OFFSET, ETH_ADDR_LEN, TRANSFER_SELECTOR, and USDC_CALLDATA_LEN.

Referenced by sign_and_broadcast().

◆ evm_fees_from_gwei()

void evm_fees_from_gwei ( uint32_t max_gwei,
uint32_t prio_gwei,
bool polygon,
uint32_t floor_gwei,
uint64_t * max_fee,
uint64_t * prio_fee )
inlinestatic

The EIP-1559 fees one EVM sale will offer, in wei per gas, from the operator's Gwei settings.

Parameters
[in]max_gweiThe Max fee setting.
[in]prio_gweiThe Priority fee setting.
[in]polygontrue on Polygon, which has a tip floor of its own.
[in]floor_gweiThat floor (POLY_MIN_PRIORITY_FEE_GWEI).
[out]max_feeFee cap, wei per gas.
[out]prio_feeTip, wei per gas; never above max_fee.

Definition at line 121 of file money.h.

Referenced by evm_fees_wei().

◆ evm_funds_check()

evm_funds_t evm_funds_check ( bool native,
uint64_t have_wei,
uint64_t gas_cost,
uint64_t units )
inlinestatic

Can have_wei pay for this sale?

Parameters
[in]nativetrue for ETH/POL; for a token only the gas is in wei.
[in]have_weiAccount balance.
[in]gas_costGas limit * max fee.
[in]unitsSale amount in keypad base units (native only).

Definition at line 159 of file money.h.

References EVM_FUNDS_OK, EVM_FUNDS_SHORT_GAS, EVM_FUNDS_SHORT_VALUE, EVM_FUNDS_UNKNOWN, and evm_units_to_wei().

Referenced by evm_balance_ok().

◆ evm_units_to_wei()

bool evm_units_to_wei ( uint64_t units,
uint64_t * wei )
inlinestatic

6-decimal keypad units -> wei, for the 18-decimal coins only.

Parameters
[in]unitsSale amount in keypad base units.
[out]weiunits * 10^12; untouched on refusal.
Returns
false past POS_AMOUNT_UNITS_MAX_NATIVE, where the multiply would wrap and sign a value nobody entered.

Definition at line 103 of file money.h.

References POS_AMOUNT_UNITS_MAX_NATIVE.

Referenced by evm_funds_check(), and sign_and_broadcast().

◆ fmt_coin()

void fmt_coin ( char * out,
size_t n,
uint64_t v,
unsigned dec,
const char * coin )
inlinestatic

"0.0013 ETH": v base units of a dec-decimal coin, to six places, rounded UP — it is a ceiling, and rounding down would understate it.

Definition at line 177 of file money.h.

Referenced by sale_fee_text().

Variable Documentation

◆ TRANSFER_SELECTOR

const uint8_t TRANSFER_SELECTOR[4] = { 0xa9U, 0x05U, 0x9cU, 0xbbU }
static

Definition at line 196 of file money.h.

Referenced by build_usdc_calldata().