写点什么

马蹄链阿凡达项目怎么玩的?合约源码公开分析

作者:加密先生
  • 2023-03-28
    广东
  • 本文字数:3541 字

    阅读完需:约 12 分钟

泰山众筹在 2 月份新上线了一个项目——SUN4.0,目前已经改名阿凡达(ANATAR),后文就以阿凡达来称呼。这个阿凡达项目运行在马蹄链上,代码完全公开,用户在没有前端的情况下,可以通过调用合约拿回自己的资金。显得非常去中心化,非常透明,非常可靠。


今天,我们就了解一下阿凡达项目的玩法和运作逻辑,以及智能合约代码的逻辑。



一、阿凡达是怎么玩的?

阿凡达(ANATAR)的玩法本身是一个存 MATIC 币,赚 Matic 币的逻辑,由合约智能执行,完全去中心化。

假设用户准备了 800 人民币用来投资,他需要先购买 Matic 代币,即马蹄币。按照 8 元一个马蹄币的价格算的话,他可以买到 100 个马蹄币。然后用户将这 800 个 Matic 以质押的形式存到 ANATAR 的智能合约里,大概是会进行如下的分配:

  • 65%~进⼊保险合约(即任何⼈动不了,⽤来保障⽤户本⾦,合约到期⾃动返回)

  • 6%~进⼊静态奖励池

  • 6%~进⼊动态奖励池直接分配完毕

  • 0.5%~进⼊后 60 名奖⾦池进⾏累计

  • 0.5%~进⼊节点分红池

  • 2%~进⼊平台盈利,这个是平台利润

例如:100 个 MATIC 进场,其中 65%进入返本池直接锁死,6%动态,2%平台,1%后 60 名爆仓奖励,26%进入收益池,也就是静态提现池,收益池提现提空了就爆仓,爆仓后 65%回本,35%出局,合约接着重启,生生不息!35%损失的,在第二次放大投资金额两倍,优先盈利,重启静态给到 1.5%的收益。

静态每天 0.3-1%,动态最高 4.8% 分六个个合约池

  • 1,自由合约(随进随出)24 小时一次

  • 2,超短合约(3-7 天)系统匹配

  • 3,短合约(8-15 天)系统匹配

  • 4,中合约(16-30 天)系统匹配

  • 5,长合约(31-90 天)

  • 6,超长合约(91-180 天)

*动态:十二个级别,V1-V12,极差 0.4%

二、阿凡达的合约代码拆解

从区块链浏览器可以发现,阿凡达项目部署了了多个合约,我们直接拆解主合约 ANATAR.sol

contract Avatar is ReentrancyGuard, Bucket {uint256 public constant PRINCIPAL_RATIO = 650000; // 65%uint256 public constant INVEST_RATIO = 260000; // 26%uint256 public constant PLATFORM_RATIO = 20000; // 2%uint256 public constant REFERRER_RATIO = 60000; // 6%uint256 public constant INCENTIVE_RATIO = 10000; // 1%uint256 public constant PRICE_PRECISION = 1e6;uint256 public constant DEFAULT_INVEST_RETURN_RATE = 10000; // 1%uint256 public constant BOOST_INVEST_RETURN_RATE = 5000; // 0.5%uint256 public constant MAX_INVEST = 1e21; // 1000uint256 public constant MIN_INVEST = 1e20; // 100uint256 public constant TIME_UNIT = 1 days;uint256[6] public DEFAULT_TARGET_AMOUNTS = [13e22, 25e22, 35e22, 50e22, 75e22, 125e22];uint256 public constant MAX_SEARCH_DEPTH = 50;uint256 public constant RANKED_INCENTIVE = 60;address public platformAddress; // will be paymentsplitter contract addressuint256[6] public currentEpochs;// ledge type => round epoch => address => position index => position infomapping(uint256 => mapping(address => PositionInfo[]))[6] public roundLedgers;//mapping(uint256 => RoundInfo)[6] public roundInfos;//mapping(address => UserRoundInfo[])[6] public userRoundsInfos;mapping(address => UserGlobalInfo) public userGlobalInfos;mapping(address => address[]) public children; // used for easily retrieve the referrer tree structure from front-end
复制代码

复制代码

该合约定义了一些常量,包括资金分配比例、价格精度、最大/最小投资金额、时间单位等。它还包含了一些结构体,例如 FundTarget、UserGlobalInfo、PositionInfo、LinkedPosition、RoundInfo 和 UserRoundInfo。

  • truct FundTarget 用于记录本轮筹资目标的情况,包括上次检查时间、目标金额和已经实现的金额。

  • struct UserGlobalInfo 记录了用户的全局信息,包括他的推荐人、推荐奖励总额、已领取的推荐奖励、加速积分、销售记录、总头寸金额、报告的销售额和销售级别。

  • struct PositionInfo 记录了用户头寸的详细信息,包括头寸金额、开仓时间、到期时间、投资回报率、已取回的金额、激励金额、投资回报金额、位置索引和是否可以领取激励。

  • struct LinkedPosition 记录了与某个回合相关联的某个头寸的地址和索引。

  • struct RoundInfo 记录了回合信息,包括筹资目标、所有头寸的总金额、当前的主要金额、当前的投资金额、所有头寸的总数、当前开放头寸的总数、当前的激励金额、激励快照、上次 N 个头寸的总数、链表中最后 N 个头寸的头节点、用户回合信息列表的本回合索引以及是否停止亏损。

  • struct UserRoundInfo 记录了用户在某个回合中的信息,包括当前的回合、总头寸金额、当前主要金额、总提取金额、总领取激励金额、总关闭头寸数和加速回报的金额。

 

function setStock(uint256 ledgerType,uint8[] calldata typeDays,uint16[] calldata stock) external {require(ledgerType > 0, "Invalid ledger type");require(ledgerType < 6, "Invalid ledger type");require(msg.sender == tempAdmin, "Only admin");require(stock.length > 0, "Invalid stock array");require(typeDays.length == stock.length, "Invalid params");_setStock(ledgerType, typeDays, stock);}function openPosition(uint256 ledgerType,uint256 targetEpoch,uint256 targetRate,address referrer,bool useBoost) external payable notContract nonReentrant {require(ledgerType < 6, "Invalid ledger type");require(targetEpoch == currentEpochs[ledgerType], "Invalid epoch");require(msg.value >= MIN_INVEST, "Too small");require(msg.value <= MAX_INVEST, "Too large");require(!gamePaused, "Paused");// load user global infoUserGlobalInfo storage userGlobalInfo = userGlobalInfos[msg.sender];// load global round infoRoundInfo storage roundInfo = roundInfos[ledgerType][targetEpoch];// placeholder for user round infoUserRoundInfo storage userRoundInfo;// determine referrer{address _referrer = userGlobalInfo.referrer;// if referrer is already set or msg.sender is the root user whose referrer is address(0)if (_referrer == address(0) && children[msg.sender].length == 0) {// if referrer is not set, set it and make sure it is a valid referrerrequire(referrer != address(0) && referrer != msg.sender, "Invalid referrer");// make sure referrer is registered alreadyrequire(userGlobalInfos[referrer].referrer != address(0) || children[referrer].length > 0,"Invalid referrer");// update storageuserGlobalInfo.referrer = referrer;children[referrer].push(msg.sender);emit NewReferrer(msg.sender, referrer);}}
复制代码

复制代码


构造函数:

  • 初始化合约时被调用,设置了三个参数:_platformAddress、_tempAdmin、_operator。

  • 对于每个参数,函数会检查它是否为 0 地址,如果是,就会抛出异常。

  • 然后,它会通过 emit NewRound() 函数发出六个事件,分别为 0 到 5,用于初始化所有轮次。

  • 最后,它会将 tempAdmin 设置为 _tempAdmin,将 operator 设置为 _operator,将 platformAddress 设置为 _platformAddress,将 gamePaused 设置为 true。

setPause() 函数:

  • 允许只有 operator 能够调用,以设置游戏的暂停状态。

  • 如果要取消暂停,函数会检查 tempAdmin 是否已被删除。如果没有被删除,函数会抛出异常。

transferOperator() 函数:

  • 允许只有 operator 能够调用,以转移操作者的身份。

  • 函数会检查新的操作者地址是否为 0 地址,如果是,就会抛出异常。

dropTempAdmin() 函数:

  • 允许只有 tempAdmin 能够调用,以删除临时管理员的身份。

  • 使用 require 语句检查调用该函数的地址是否为临时管理员地址,若不是则会抛出异常。

  • 将临时管理员地址设置为 0

batchSetReferrerInfo 函数:

  • 此函数用于为多个用户设置推荐人信息。

  • 函数接受三个数组类型的参数:users、referrers 和 salesLevels,分别表示需要设置推荐人信息的用户、他们的推荐人和销售级别。

  • 使用 require 语句检查调用该函数的地址是否为临时管理员地址,若不是则会抛出异常。

  • 使用 require 语句检查 users、referrers 和 salesLevels 数组的长度是否相等,若不相等则会抛出异常。


三、开发一个类似阿凡达的项目难不难

阿凡达项目的开发,主要是在两个方面:前端页面和后端的合约。DAPP 前端的页面,包括设计、交互、操作等等,相对来说不是非常的复杂。但是后端的这个合约,就比较困难了。这个合约的设计极为复杂,且具有一定水平。光是拆解,几千字都写不完。大家如果有兴趣,欢迎联系我讨论。

用户头像

加密先生

关注

区块链dapp开发,v:btc6540 2023-02-07 加入

区块链工程师,专业开发

评论

发布
暂无评论
马蹄链阿凡达项目怎么玩的?合约源码公开分析_加密先生_InfoQ写作社区