解读EOSIO RAM价格大幅波动背后的Bancor算法

概要

EOSIO 的 RAM 从主网启动到现在, 经过了大幅的价格波动, 其背后的 Bancor 算法定价机制也引起了广泛关注。本文参考了 Bancor 白皮书,结合 EOSIO 的的代码, 分析了 Bancor算法和在 EOSIO 中的具体实现代码, 帮助开发者更好地理解 Bancor 算法原理。

什么是Bancor 协议

Bancor 协议通过智能合约为加密货币提供持续的流动性,每个smart token 可以有1个或多个连接到其他token的连接器, 允许用户通过合约买卖连接的其他token, 通过算法来不断更新买卖价格, 平衡供求关系。

算法原理

Bancor 协议使用算法计算smart token 和connected token 之间兑换关系,计算方式如下:
connector weight 代表smart token 的流通市值和connector token 余额之间的比例:

其中

一般来说, 较高的CW 带来较低的价格敏感性; 较低的CW 会导致较高的价格敏感性 。CW 的值一般在 (0, 1] 之间, 下图是不同的CW对应的价格模型

理论上, CW 也可以设置为大于1的值,这会导致当需求增加时token的价格反而会降低, 或许可以应用在P2P file sharing 网络中,随着加入网络的节点增多,使用成本可以降低。

既然每次买卖行为都会导致价格波动, 那实际购买的价格是如何确定呢? 我们有下面的公式:具体推导的过程可以参考Rosenfeld的论文

买入时可以兑换的smart token:


卖出时需要支付的connector token:

则实际兑换价格公式如下:

举例如下:
假设smart token 为ABC, connector token 为EOS,初始设置如下:

CW:0.5

Balance(EOS):250

Supply (ABC):1000

Price:250/(1000*0.5) = 0.5

假设买家想用10个EOS 购买ABC, 那可以获得多少个ABC呢, 按照上面的公式, 可以得出:

实际购买价格如下:

下面是连续几次买卖后的结果, 可以看出,每次买卖行为都会导致价格波动。


前3次交易每次用10个EOS 购买ABC,可交换的ABC 数额逐渐下降,驱动ABC价格上升;
后3次交易每次卖10个ABC换取EOS, 可交换的EOS 数额逐渐下降,驱动ABC价格下降。

Bancor生态

通过bancor协议实现去中心化的流动性,整个生态由不同的用户组成:

  • Traders
    终端用户, 持有、买卖smart token
  • Smart Token Issuers
    智能token 发行者
  • Asset Tokenizers
    把现实世界中的资产通证化并流通
  • Arbitrageurs
    如果市场价格高于Smart Token报价,任何人都可以从Smart Token购买并在市场上出售,直到价格均匀。套利能力有效激励市场参与者在Smart Token 和外部价格之间建立价格共识。

EOSIO中的Bancor算法

EOSIO 在设计中也用到了Bancor算法, 具体体现在2个方面:RAM资源和Exchange合约。

RAM资源

EOSIO 中的RAM,作为系统资源, 用来存储账户相关信息,例如公钥、余额, 和智能合约状态等数据。 由于单个计算机可用的RAM数量受到摩尔定律和其他技术进步的限制,因此RAM本质上是稀缺的。为了有效利用系统资源,EOSIO 引入了Bancor算法,允许用户从系统购买RAM 资源,也可以出售RAM资源给系统换取EOS。

那么具体到代码是如何实现的呢, 它利用了Bancor Relay Token。 简单来说就是一个smart token A 有2个connector token, B 和 C,允许用户通过2步购买的方式, 实现B 和C 之间的交易。 具体到RAM, 主要实现代码在eosio.system/exchange_state.hpp 和 eosio.system/exchange_state.cpp。

初始化代码如下:

auto system_token_supply   = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount;
         if( system_token_supply > 0 ) {
            itr = _rammarket.emplace( _self, [&]( auto& m ) {
               m.supply.amount = 100000000000000ll;
               m.supply.symbol = S(4,RAMCORE);
               m.base.balance.amount = int64_t(_gstate.free_ram());
               m.base.balance.symbol = S(0,RAM);
               m.quote.balance.amount = system_token_supply / 1000;
               m.quote.balance.symbol = CORE_SYMBOL;
            });
         }

其中RAMCORE 就是relay token, 有2个connector token, 分别是EOS 和 RAM。
2个connector token之间的转换是通过relay token RAMCORE 来完成的,比如用EOS购买RAM 的流程如下:
EOS –> RAMCORE –> RAM, 反之亦然。

系统合约中提供了买卖RAM 的方法,

  • buyram
  • buyrambytes
  • sellram

虽然可以买卖RAM, 但是系统做了限制, 用户之间不能交易RAM。 另外买卖RAM 各收取0.5%的手续费。

价格走势

Bancor算法通过智能合约为数字货币提供了持续的流动性。 从主网激活到现在,很多人炒作RAM,从中获利, 导致价格波动很大。

算法差异

EOS 中实现的算法和白皮书中的算法略有差异,主要体现在转换算法上:
白皮书中:
tokens issued 在计算时的balance 是购买之前的balance.

connected tokens paied out 是卖出之前的supply

而EOSIO中这2个值全部用的是买卖动作之后的值

asset exchange_state::convert_to_exchange( connector& c, asset in ) {

      real_type R(supply.amount);
      real_type C(c.balance.amount+in.amount);
                                  ^^^^^^^^^^^^ This amount should not be added.
      real_type F(c.weight/1000.0);
      real_type T(in.amount);
      real_type ONE(1.0);

      real_type E = -R * (ONE - std::pow( ONE + T / C, F) );
      //print( "E: ", E, "\n");
      int64_t issued = int64_t(E);

      supply.amount += issued;
      c.balance.amount += in.amount;

      return asset( issued, supply.symbol );
   }

   asset exchange_state::convert_from_exchange( connector& c, asset in ) {
      eosio_assert( in.symbol== supply.symbol, "unexpected asset symbol input" );

      real_type R(supply.amount - in.amount);
                                  ^^^^^^^^^^^^ This amount should not be subtracted
      real_type C(c.balance.amount);
      real_type F(1000.0/c.weight);
      real_type E(in.amount);
      real_type ONE(1.0);


     // potentially more accurate: 
     // The functions std::expm1 and std::log1p are useful for financial calculations, for example, 
     // when calculating small daily interest rates: (1+x)n
     // -1 can be expressed as std::expm1(n * std::log1p(x)). 
     // real_type T = C * std::expm1( F * std::log1p(E/R) );

      real_type T = C * (std::pow( ONE + E/R, F) - ONE);
      //print( "T: ", T, "\n");
      int64_t out = int64_t(T);

      supply.amount -= in.amount;
      c.balance.amount -= out;

      return asset( out, c.balance.symbol );
   }

BM 的解释是白皮书的算法是有问题的, 但是从算法推导过程来看,并没有什么问题,可能是基于其它方面的考量。

Exchange合约

Exchange 合约是基于bancor 算法实现的一套去中心化交易算法。 通过bancor算法,可以创建任意2个token之间的交易对。 这个合约实现了以下方法:

这个合约只是个demo,并不完善,转账需要授权给exchange合约, 而目前EOSIO 在这方面是有安全风险的, 暂时不推荐使用。

总结

通过Bancor算法可以很方便地实现数字资产之间的流转, bancor 算法可以运用在去中心化交易所, 虚拟资产流转等方面。 据统计, 在数字资产的交易中, 前10%的持有者占据了整个市场95%的数字资产, 以及99%的交易量。大部分数字资产存在流动性不够的问题, bancor算法通过程序来动态调整价格,客观上可以解决流动性不足的问题。 在EOSIO的RAM 设计中, 通过引入bancor算法,让市场定价, 满足了RAM 流动需要,但是同时也带了一些新的问题,一方面, 保持RAM作为系统资源的稀缺性可以降低全节点的成本,但是却增加了和用户和EOSIO的交互成本,这也是接下来社区要解决的问题。

参考链接

https://storage.googleapis.com/website-bancor/2018/04/01ba8253-bancor_protocol_whitepaper_en.pdf

https://drive.google.com/file/d/0B3HPNP-GDn7aRkVaV3dkVl9NS2M/view

https://medium.com/@bytemaster/eosio-ram-market-bancor-algorithm-b8e8d4e20c73

https://github.com/EOSIO/eos/issues/3032

https://eosio.stackexchange.com/questions/317/is-there-a-math-error-in-bancor-paper

https://github.com/eosio/eos

https://eos.feexplorer.io/

https://www.bancor.network/

猜你喜欢

转载自blog.csdn.net/shangsongwww/article/details/123596166