Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 1 addition & 57 deletions contracts/ContinuousOffering.sol
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ contract ContinuousOffering
address indexed _from,
uint _fairValue
);
event Close(
uint _exitFee
);
event StateChange(
uint _previousState,
uint _newState
Expand Down Expand Up @@ -935,63 +932,16 @@ contract ContinuousOffering

/// Close

function estimateExitFee(
uint _msgValue
) public view
returns(uint)
{
uint exitFee;

if(state == STATE_RUN)
{
uint reserve = buybackReserve();
reserve = reserve.sub(_msgValue);

// Source: t*(t+b)*(n/d)-r
// Implementation: (b n t)/d + (n t^2)/d - r

uint _totalSupply = totalSupply();

// Math worst case:
// MAX_BEFORE_SQUARE * MAX_BEFORE_SQUARE/2 * MAX_BEFORE_SQUARE
exitFee = BigDiv.bigDiv2x1(
_totalSupply,
burnedSupply * buySlopeNum,
buySlopeDen
);
// Math worst case:
// MAX_BEFORE_SQUARE * MAX_BEFORE_SQUARE * MAX_BEFORE_SQUARE
exitFee += BigDiv.bigDiv2x1(
_totalSupply,
buySlopeNum * _totalSupply,
buySlopeDen
);
// Math: this if condition avoids a potential overflow
if(exitFee <= reserve)
{
exitFee = 0;
}
else
{
exitFee -= reserve;
}
}

return exitFee;
}

/// @notice Called by the beneficiary account to STATE_CLOSE or STATE_CANCEL the c-org,
/// preventing any more tokens from being minted.
/// @dev Requires an `exitFee` to be paid. If the currency is ETH, include a little more than
/// what appears to be required and any remainder will be returned to your account. This is
/// because another user may have a transaction mined which changes the exitFee required.
/// For other `currency` types, the beneficiary account will be billed the exact amount required.
function close() public payable
function _close() internal
{
require(msg.sender == beneficiary, "BENEFICIARY_ONLY");

uint exitFee = 0;

if(state == STATE_INIT)
{
// Allow the org to cancel anytime if the initGoal was not reached.
Expand All @@ -1004,19 +954,13 @@ contract ContinuousOffering
require(MAX_UINT - minDuration > runStartedOn, "MAY_NOT_CLOSE");
require(minDuration + runStartedOn <= block.timestamp, "TOO_EARLY");

exitFee = estimateExitFee(msg.value);

emit StateChange(state, STATE_CLOSE);
state = STATE_CLOSE;

_collectInvestment(msg.sender, exitFee, msg.value, true);
}
else
{
revert("INVALID_STATE");
}

emit Close(exitFee);
}

// --- Approve by signature ---
Expand Down
70 changes: 70 additions & 0 deletions contracts/DecentralizedAutonomousTrust.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,81 @@ import "./ContinuousOffering.sol";
*/
contract DecentralizedAutonomousTrust is ContinuousOffering
{
event Close(
uint _exitFee
);
event Pay(
address indexed _from,
uint _currencyValue
);

/// Close

function estimateExitFee(
uint _msgValue
) public view
returns(uint)
{
uint exitFee;

if(state == STATE_RUN)
{
uint reserve = buybackReserve();
reserve = reserve.sub(_msgValue);

// Source: t*(t+b)*(n/d)-r
// Implementation: (b n t)/d + (n t^2)/d - r

uint _totalSupply = totalSupply();

// Math worst case:
// MAX_BEFORE_SQUARE * MAX_BEFORE_SQUARE/2 * MAX_BEFORE_SQUARE
exitFee = BigDiv.bigDiv2x1(
_totalSupply,
burnedSupply * buySlopeNum,
buySlopeDen
);
// Math worst case:
// MAX_BEFORE_SQUARE * MAX_BEFORE_SQUARE * MAX_BEFORE_SQUARE
exitFee += BigDiv.bigDiv2x1(
_totalSupply,
buySlopeNum * _totalSupply,
buySlopeDen
);
// Math: this if condition avoids a potential overflow
if(exitFee <= reserve)
{
exitFee = 0;
}
else
{
exitFee -= reserve;
}
}

return exitFee;
}

/// @notice Called by the beneficiary account to STATE_CLOSE or STATE_CANCEL the c-org,
/// preventing any more tokens from being minted.
/// @dev Requires an `exitFee` to be paid. If the currency is ETH, include a little more than
/// what appears to be required and any remainder will be returned to your account. This is
/// because another user may have a transaction mined which changes the exitFee required.
/// For other `currency` types, the beneficiary account will be billed the exact amount required.
function close() public payable
{
uint exitFee = 0;

if(state == STATE_RUN)
{
exitFee = estimateExitFee(msg.value);
_collectInvestment(msg.sender, exitFee, msg.value, true);
}

super._close();
emit Close(exitFee);
}

/// Pay

/// @dev Pay the organization on-chain.
Expand Down