Cómo imponer un bloqueo de tiempo || Adquisición de tokens ERC20 durante ICO (Crowdsale)

Hola, estoy escribiendo un crowdsale usando Zeppelin-Solidity donde necesito integrar la función de bloqueo de tokens para que los tokens ERC20 puedan bloquearse por un período de tiempo específico.

La solidez del zepelín parece proporcionar Tokenvesting.sol para este propósito.

pragma solidity ^0.4.11;

import './ERC20Basic.sol';
import './SafeERC20.sol';
import '../ownership/Ownable.sol';
import '../math/Math.sol';
import '../math/SafeMath.sol';

/**
 * @title TokenVesting
 * @dev A token holder contract that can release its token balance gradually like a
 * typical vesting scheme, with a cliff and vesting period. Optionally revocable by the
 * owner.
 */
contract TokenVesting is Ownable {
  using SafeMath for uint256;
  using SafeERC20 for ERC20Basic;

  event Released(uint256 amount);
  event Revoked();

  // beneficiary of tokens after they are released
  address public beneficiary;

  uint256 public cliff;
  uint256 public start;
  uint256 public duration;

  bool public revocable;

  mapping (address => uint256) public released;
  mapping (address => bool) public revoked;

  /**
   * @dev Creates a vesting contract that vests its balance of any ERC20 token to the
   * _beneficiary, gradually in a linear fashion until _start + _duration. By then all
   * of the balance will have vested.
   * @param _beneficiary address of the beneficiary to whom vested tokens are transferred
   * @param _cliff duration in seconds of the cliff in which tokens will begin to vest
   * @param _duration duration in seconds of the period in which the tokens will vest
   * @param _revocable whether the vesting is revocable or not
   */
  function TokenVesting(address _beneficiary, uint256 _start, uint256 _cliff, uint256 _duration, bool _revocable) {
    require(_beneficiary != address(0));
    require(_cliff <= _duration);

    beneficiary = _beneficiary;
    revocable = _revocable;
    duration = _duration;
    cliff = _start.add(_cliff);
    start = _start;
  }

  /**
   * @notice Transfers vested tokens to beneficiary.
   * @param token ERC20 token which is being vested
   */
  function release(ERC20Basic token) public {
    uint256 unreleased = releasableAmount(token);

    require(unreleased > 0);

    released[token] = released[token].add(unreleased);

    token.safeTransfer(beneficiary, unreleased);

    Released(unreleased);
  }

  /**
   * @notice Allows the owner to revoke the vesting. Tokens already vested
   * remain in the contract, the rest are returned to the owner.
   * @param token ERC20 token which is being vested
   */
  function revoke(ERC20Basic token) public onlyOwner {
    require(revocable);
    require(!revoked[token]);

    uint256 balance = token.balanceOf(this);

    uint256 unreleased = releasableAmount(token);
    uint256 refund = balance.sub(unreleased);

    revoked[token] = true;

    token.safeTransfer(owner, refund);

    Revoked();
  }

  /**
   * @dev Calculates the amount that has already vested but hasn't been released yet.
   * @param token ERC20 token which is being vested
   */
  function releasableAmount(ERC20Basic token) public constant returns (uint256) {
    return vestedAmount(token).sub(released[token]);
  }

  /**
   * @dev Calculates the amount that has already vested.
   * @param token ERC20 token which is being vested
   */
  function vestedAmount(ERC20Basic token) public constant returns (uint256) {
    uint256 currentBalance = token.balanceOf(this);
    uint256 totalBalance = currentBalance.add(released[token]);

    if (now < cliff) {
      return 0;
    } else if (now >= start.add(duration) || revoked[token]) {
      return totalBalance;
    } else {
      return totalBalance.mul(now.sub(start)).div(duration);
    }
  }
}
© 2017 GitHub, Inc.

Pero hay diferentes parámetros en él (inicio, período de consolidación y precipicio). No estoy seguro de cómo funcionará esto

-Si los tokens se transfieren primero al beneficiario y luego se bloquean o los tokens se almacenan en un contrato bloqueado y se liberan más tarde. Y cómo funciona la adquisición de derechos y el acantilado. He investigado la concesión y el acantilado en Investopedia , pero no aclara el concepto de cómo se describirá esto con respecto a la venta colectiva (acantilado, Adquisición y revocación)

Respuestas (1)

La adquisición de un acantilado es un requisito típico para los fundadores que tienen acciones de una empresa, por lo que no abandonan la empresa cuando más se los necesita con las acciones que tienen. El mismo concepto se ha traducido a las ICO para que los fundadores (y los miembros clave del equipo, asesores, etc.) no se deshagan de sus tokens tan pronto como se incluyan en los intercambios.

El período de consolidación se refiere a la duración de la concesión. Por ejemplo, si el período de adjudicación es de 48 meses (4 años sería un período de adjudicación típico para los fundadores), esto significa que cada mes que aún estoy en la empresa, se me liberará 1/48 de las acciones a las que tengo derecho. . Entonces, si por alguna razón dejo la compañía solo después de 24 meses, solo obtendré la mitad de las acciones que "tenía".

A veces también se agrega un acantilado a la ecuación. Un precipicio determinará cuándo se me entregarán todas estas acciones que acumulé. Por ejemplo, si hay un precipicio de 1 año y un período de adjudicación de 4 años, si dejo la empresa en cualquier momento antes de que haya pasado el período del precipicio (del mes 1 al 12), no obtendré nada. Si me voy el mes 13, obtengo 13/48 de mis acciones.

En caso de que alguien no haya cumplido el período de carencia y se vaya con menos acciones a las que tenía derecho, el resto de las acciones se devuelven a la empresa para que las use como quiera. En el caso de la venta de tokens, los tokens serán devueltos al titular del contrato.

Entonces, en este contrato en particular, cuando la venta colectiva finaliza con éxito, en lugar de transferir los tokens a los fundadores, asesores o miembros del equipo directamente, puede usar este contrato para establecer la concesión. Digamos que tengo derecho a 1200 tokens que deberían otorgarse en 12 meses con un precipicio de 6 meses.

  • Mes 1: recibo 0 tokens
  • Mes 2: obtengo 0 tokens
  • Mes 3: obtengo 0 tokens
  • Mes 4: recibo 0 tokens
  • Mes 5: recibo 0 tokens
  • Mes 6: Obtengo 0 tokens --------- Fin del precipicio
  • Mes 7: obtengo 700 tokens (7/12)
  • Mes 8: obtengo 100 tokens (8/12)
  • Mes 9: obtengo 100 fichas (9/12)
  • Mes 10: obtengo 100 tokens (10/12)
  • Mes 11: obtengo 100 tokens (11/12)
  • Mes 12: obtengo 100 tokens (12/12)

Primero, implementaría el contrato y llamaría a tokenVesting() pasando mi dirección, cuando esto comience (ahora), el acantilado será de 6 meses (en segundos), la duración será de 12 meses (en segundos) y el booleano revocable. La bandera revocable le permite al propietario revocar la concesión de tokens pendiente para el beneficiario, por lo que, si esa persona deja la empresa, ya no tendrá derechos.

Luego, en cualquier momento, el beneficiario puede llamar a release() para calcular cuántos tokens ya se le otorgaron y transferirlos.

Tenga en cuenta que, a diferencia de mi explicación anterior (que proviene de haber trabajado en una empresa de capital de riesgo con esquemas de adjudicación más tradicionales), la adjudicación no se divide en meses. La adjudicación se calcula en segundos, por lo que puede obtener una adjudicación más granular. (si la duración es de 100.000 segundos, podría llamar a esta función cada segundo para obtener mi correspondiente 1/100.000 de tokens).

Gracias por una respuesta tan elaborada a mi pregunta @pabloruiz55. Esto me ayudaría mucho a desarrollar una mejor comprensión sobre la adquisición de derechos en las ICO.