This document describes the required deployment sequence for the Creditra Credit contract and the invariants that operators must maintain.
The following steps must be performed in order immediately after deployment. Skipping or reordering steps will leave the contract in an unusable or insecure state.
Deploy the compiled WASM to the Stellar network using the Soroban CLI or SDK. Note the resulting contract address.
init is a one-time operation protected by an AlreadyInitialized guard:
pub fn init(env: Env, admin: Address)- Stores
adminin instance storage under the"admin"key. - Sets
LiquiditySourceto the contract's own address as the default reserve.
- It does not emit an event.
- It does not set a liquidity token (that requires a separate call).
- A second call to
initwith any address reverts withContractError::AlreadyInitialized(error code 14). - The admin address is immutable after the first successful
initcall. - No state is mutated on a failed re-init attempt.
soroban contract invoke \
--id $CONTRACT_ID \
--source $DEPLOYER_KEY \
-- init \
--admin $ADMIN_ADDRESSWithout a liquidity token, draw operations transfer no tokens (state-only accounting). Set the token before opening credit lines that will be drawn:
soroban contract invoke \
--id $CONTRACT_ID \
--source $ADMIN_KEY \
-- set_liquidity_token \
--token_address $TOKEN_ADDRESSBy default the contract itself is the liquidity reserve. To use an external reserve (e.g. a multisig treasury):
soroban contract invoke \
--id $CONTRACT_ID \
--source $ADMIN_KEY \
-- set_liquidity_source \
--reserve_address $RESERVE_ADDRESSThe guard is implemented in contracts/credit/src/config.rs:
if env.storage().instance().has(&admin_key(&env)) {
env.panic_with_error(ContractError::AlreadyInitialized);
}This fires before any storage write, so a failed re-init leaves the contract state completely unchanged.
ContractError::AlreadyInitialized = 14
# A second init call should return Error(Contract, #14)
soroban contract invoke \
--id $CONTRACT_ID \
--source $ANY_KEY \
-- init \
--admin $ANY_ADDRESS
# Expected: Error(Contract, #14)The admin address is currently immutable after init. A safe rotation design
(propose + accept two-step pattern) is planned. Until then, protect the admin
key with a hardware wallet or multisig.
| File | Role |
|---|---|
contracts/credit/src/config.rs |
init, set_liquidity_token, set_liquidity_source |
contracts/credit/src/storage.rs |
admin_key, DataKey |
contracts/credit/src/types.rs |
ContractError::AlreadyInitialized |
contracts/credit/tests/init_idempotency.rs |
Tests for init guard |