Sai Teller
Sai有时指整个系统。在本文中,Sai特指Sai L1,即Nibiru上的Sai Wasm合约。
Teller Deposit让Sai识别受支持源链上的存款,并在结算前允许其权益用于交易。Direct Deposit使用用户已在Sai L1上持有的Sai USDC,抵押资产随调用一起到达。
以下术语区分源链资金、Sai在结算前授予的信用,以及结算时到达的Sai USDC抵押资产。Sai USDC1由Base枢纽持有的USDC支持。该枢纽连接受支持的源链与Sai L1,即Nibiru。
阅读定义后,再看存款与分配示例,了解结算状态和权益位置如何独立变化。后面的实现部分说明合约调用与存储。SVG中的技术标签保留英文。
| 术语 | 定义 |
|---|---|
| Teller Deposit | 通过Teller接受并单独跟踪的源链存款。Sai使用路由ID和源存款索引识别它,结算后仍保留同一身份。 |
| Direct Deposit | 用户将已在Sai L1,即Nibiru上持有的Sai USDC存入Sai。抵押资产随存款调用一起到达,因此Sai立即增加用户已有资产支持的存款余额。 |
| Teller Deposit Credit | Sai接受经过验证的源存款证据,并针对该Teller Deposit授予可交易但不可提现的权益。此调用不附带抵押资产,也不铸造Sai USDC。 |
| 未结算的Teller Deposit | Sai已授予Teller Deposit Credit,但尚未应用对应支持资产的存款。源交易本身可能已经确认。 |
| 已结算的Teller Deposit | Sai收到并应用支持资产之后的同一笔存款。其权益仍可留在未平仓仓位中。 |
| 结算 | 应用已交付抵押资产,为现有Teller Deposit Credit提供支持的操作。需要完整的原始本金,不会再次授予信用,也不会平仓。 |
| 源链USDC | Circle在Base等受支持的源链上发行的USDC。 |
| Sai USDC | Nibiru上的ERC20代币,代表锁定在Teller系统Base金库中的USDC。FunToken映射可在ERC20表示和Sai Wasm合约使用的对应银行模块代币面额之间转换。 |
| 本金 | Teller Deposit的原始存入金额。交易不会改变结算必须交付的金额。 |
| 权益 | 计入手续费、盈亏和仓位变化后,归属于某笔Teller Deposit的价值。可以空闲,也可以分配给仓位。 |
| 空闲权益 | 可用于仓位的权益。未结算时不可提现。结算后剩余的空闲权益加入用户已有资产支持的存款余额。 |
| 分配 | 记录仓位中有多少权益归属于特定Teller Deposit的会计关联。它包含存款键和权益金额,不是另一种代币或额外用户余额。 |
| 存款余额 | 用户在Sai内有资产支持且处于空闲状态的资金总额。与未平仓仓位权益和未结算Teller权益分开。 |
| 延迟效果 | 已记录的手续费或转账义务,需要等待源Teller Deposit的支持资产到达。结算应用已记录的会计变化,并发出延迟转账消息。 |
| 证明者 | 验证源证据并签名的主体。Sai根据路由授权的签名者集合验证签名。 |
| 操作员 | 获授权提交某路由Teller Deposit Credit或结算交易的账户。合约所有者也可提交。操作员权限不能代替Teller Deposit Credit所需的证明者签名。 |
| 路由 | 由源链ID、Teller合约地址和源USDC地址组成的源身份。配置包括证明者、限额和暂停状态。 |
Teller Deposit Credit与Sai的USDC交易信用计划是不同功能。后者是带有独立限制的已注资资本功能。两者使用相同的已配置USDC抵押资产索引,但余额和会计记录分开。
Sai USDC的支持资产与Teller结算
Section titled “Sai USDC的支持资产与Teller结算”Teller系统在Base金库中持有支持USDC,并以此在Nibiru上铸造Sai USDC。用户可持有、转移或将Sai USDC存入Sai。把现有Sai USDC移入Sai不会增加代币供应量。
Teller Deposit Credit不铸造Sai USDC。 它根据已验证的源证据记录可交易权益。之后,结算将对应的Sai USDC银行模块抵押资产交付并应用到Sai。全局代币支持与Sai中单笔存款的结算是不同的会计事项。
Trade模式将资金送入Sai,Bridge模式将Sai USDC送到用户钱包。用户之后把钱包中的Sai USDC存入Sai时,执行的是Direct Deposit,即使这些代币最初来自Teller。
同一笔存款改变状态,权益可以移动
Section titled “同一笔存款改变状态,权益可以移动”Alice的Teller Deposit原始本金为300 USDC。她把200用于仓位X,留下100空闲。结算提供原始本金300。空闲100加入已有资产支持的存款余额,仓位内的200作为已有资产支持的权益保留。
| 属性 | 回答的问题 | 值 |
|---|---|---|
| 结算状态 | Sai是否已应用这笔存款的支持资产? | 未结算或已结算 |
| 权益位置 | 用户如何使用这部分权益? | 空闲或已分配给仓位 |
两种属性相互独立。Teller Deposit在结算时保留身份,不会拆分成已结算和未结算的两笔存款。
此示例忽略手续费、盈亏和其他资金来源。金额以USDC计,结算交付对应的Sai USDC银行模块抵押资产。
Sai授予Teller Deposit Credit后,未结算权益即可用于交易。提现需要等待结算应用支持资产。
分配连接仓位与Teller Deposit
Section titled “分配连接仓位与Teller Deposit”一个仓位可使用多笔Teller Deposit的权益。Sai为每笔来源存款分别记录分配,以跟踪手续费、抵押资产释放和结算。
这里,存款A提供300,存款B提供100,共同构成权益400 USDC的仓位。B还剩100空闲权益。只有A结算后,仓位包含300已有资产支持的权益和100未结算权益。B的空闲100也仍未结算。
结算后,分配仍可记录仓位权益的资金归属。手续费和仓位变化可调整其金额。已有资产支持的空闲资金汇总到用户存款余额,因此Sai不会为每笔已结算Teller Deposit分别保留空闲余额。
使用未结算权益交易,可能在支持资产到达前产生手续费或金库转账义务。延迟效果记录这些义务,结算应用会计变化并发出延迟转账消息。
Teller Deposit Credit与结算使用不同调用
Section titled “Teller Deposit Credit与结算使用不同调用”证明者签署源证据,获授权的操作员提交Teller Deposit Credit请求。之后到达的抵押资产支持同一笔存款。用户可在两次调用之间交易。
CreditTellerDeposit → contract::execute → exec_credit_deposit
FundTradeMint + bank coins → contract::execute → exec_fund_trade_mint → settle_confirmed_range
SettleTellerBatch + bank coins → contract::execute → exec_settle_batch → settle_confirmed_range消息FundTradeMint要求配置的桥接地址调用。SettleTellerBatch要求路由操作员或所有者调用,可为连续的存款范围提供资金。两者均要求完整原始本金。结算顺序遵循各路由的信用记录索引。
消息名中的Mint不表示Sai Wasm合约铸造Sai USDC或开仓。处理函数负责对收到的银行模块抵押资产记账。
Sai如何处理桥接资金
Section titled “Sai如何处理桥接资金”处理函数首先检查CCTP存款查找表,防止到达的资金绕过已有Teller Deposit Credit。
| CCTP查找结果 | 源链路由 | 结果 |
|---|---|---|
| 已知存款 | 必须匹配该存款路由 | 验证身份并结算,检查失败则拒绝。 |
| 无已知存款 | 存在路由 | 以TellerDepositNotCredited拒绝,记录信用后重试。 |
| 无已知存款 | 无路由 | 立即增加指定用户已有资产支持的存款余额。 |
最后一个分支使用与Direct Deposit相同的内部存款函数,但它是桥接资金的代码路径。本文的Direct Deposit专指使用Sai L1上已经持有的Sai USDC进行存款的用户流程。
存款身份与用户余额使用不同的键
Section titled “存款身份与用户余额使用不同的键”路由识别源链、Teller合约和源USDC合约。每笔Teller Deposit在该路由内有独立索引。用户权益总额可汇总多个有效路由的存款。
| 标识符 | 含义 |
|---|---|
| 路由ID | 源链ID、Teller地址和源USDC地址的哈希。 |
| Teller Deposit键 | route_id与deposit_idx组成的键,每个路由的存款索引从1开始。 |
| 源存款ID | 绑定路由、存款索引、源发送者和原始金额。 |
| CCTP存款ID | 将到达的资金连接到现有Teller Deposit Credit,也是签名证据的一部分。 |
| 用户队列序号 | 跨路由记录用户存款的顺序,从0开始,与源存款索引独立。 |
映射USER_TELLER_STATE为每位用户保存一条TellerUserState。字段unsettled_idle和unsettled_in_trades记录两种权益位置,next_deposit_sequence和deposit_cursor记录队列进度。队列项保留在独立映射USER_TELLER_DEPOSIT_QUEUE中,因此Sai可以逐项读取或删除,而无需重写整个队列。会计辅助函数在每个操作中读取最新用户状态,检查运算后更新。
函数teller_usdc_collateral读取配置项TRADING_CREDIT_COLLATERAL_IDX,与USDC交易信用计划共用该配置。Teller余额只需用户键,队列使用用户和序号键。这是可配置的索引,不是跨链通用的固定数字。其他抵押资产的交易和查询不能使用或显示这部分Teller权益。
命名空间使用字面前缀teller/,例如teller/route_cfgs和teller/deposits。迁移11重命名旧命名空间,从用户键中移除冗余抵押资产索引,并将四个旧用户值合并到TellerUserState中。保留的Rust类型名TellerTradeLotAllocation中的Lot表示Teller Deposit。
- Sai Keeper Teller架构说明Base金库、Sai USDC、Trade和Bridge模式及桥接组件。
- Sai Teller代码定义本页使用的会计行为和存储名称。
配置的桥接地址也有权调用DebitDepositToBridge,扣除指定用户已有资产支持的空闲余额并转给桥接合约。因此,桥接合约必须在提现流程中验证用户授权。
Footnotes
Section titled “Footnotes”-
Sai USDC有时也称为Nibiru USDC。 ↩