Skip to content

Commit

Permalink
Merge branch 'main' into feat/88/compile
Browse files Browse the repository at this point in the history
  • Loading branch information
sirnicolaz authored Nov 10, 2023
2 parents 65fbc53 + 4d78acf commit ce80a89
Show file tree
Hide file tree
Showing 49 changed files with 1,034 additions and 128 deletions.
596 changes: 578 additions & 18 deletions .openzeppelin/unknown-9001.json

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,12 @@ npx hardhat test
# Deploy to production
npx hardhat deploy --network evmos
```

# Audits

- [SolidProof](https://solidproof.io/)
- Tag: https://github.com/NeokingdomDAO/contracts/releases/tag/audit1
- Report: https://github.com/solidproof/projects/blob/main/2023/NeokingdomDAO/SmartContract_Audit_Solidproof_NeoKingdomDAO.pdf
- [LeastAuthority](https://leastauthority.com)
- Tag: https://github.com/NeokingdomDAO/contracts/releases/tag/audit2
- Report: https://leastauthority.com/blog/audits/neokingdom-dao-smart-contracts/
34 changes: 21 additions & 13 deletions contracts/GovernanceToken/GovernanceToken.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
pragma solidity 0.8.16;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
Expand Down Expand Up @@ -46,6 +46,10 @@ contract GovernanceToken is Initializable, HasRole, GovernanceTokenSnapshot {
string memory name,
string memory symbol
) public initializer {
require(
address(roles) != address(0),
"GovernanceToken: 0x0 not allowed"
);
_initialize(name, symbol);
_setRoles(roles);
}
Expand Down Expand Up @@ -154,6 +158,15 @@ contract GovernanceToken is Initializable, HasRole, GovernanceTokenSnapshot {
uint256 amount
) public virtual onlyRole(Roles.RESOLUTION_ROLE) {
_mint(to, amount);

if (
_shareholderRegistry.isAtLeast(
_shareholderRegistry.CONTRIBUTOR_STATUS(),
to
)
) {
_redemptionController.afterMint(to, amount);
}
}

/**
Expand Down Expand Up @@ -292,16 +305,6 @@ contract GovernanceToken is Initializable, HasRole, GovernanceTokenSnapshot {
super._afterTokenTransfer(from, to, amount);
_voting.afterTokenTransfer(from, to, amount);

if (
from == address(0) &&
_shareholderRegistry.isAtLeast(
_shareholderRegistry.CONTRIBUTOR_STATUS(),
to
)
) {
_redemptionController.afterMint(to, amount);
}

// Invariants
require(
balanceOf(from) >= _vestingBalance[from],
Expand Down Expand Up @@ -342,7 +345,12 @@ contract GovernanceToken is Initializable, HasRole, GovernanceTokenSnapshot {
* @param amount Amount of external tokens to wrap.
*/
function _wrap(address from, uint amount) internal virtual {
tokenExternal.transferFrom(from, address(this), amount);
require(
tokenExternal.transferFrom(from, address(this), amount),
"GovernanceToken: transfer failed"
);
require(amount > 0, "GovernanceToken: attempt to wrap 0 tokens");

uint256 settlementTimestamp = block.timestamp + settlementPeriod;
depositedTokens[from].push(
DepositedTokens(amount, settlementTimestamp)
Expand All @@ -360,7 +368,7 @@ contract GovernanceToken is Initializable, HasRole, GovernanceTokenSnapshot {
DepositedTokens storage tokens = depositedTokens[from][i - 1];
if (block.timestamp >= tokens.settlementTimestamp) {
if (tokens.amount > 0) {
super._mint(from, tokens.amount);
ERC20Upgradeable._mint(from, tokens.amount);
tokens.amount = 0;
} else {
break;
Expand Down
8 changes: 5 additions & 3 deletions contracts/GovernanceToken/GovernanceTokenBase.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;
pragma solidity 0.8.16;

import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "../RedemptionController/IRedemptionController.sol";
Expand Down Expand Up @@ -69,7 +68,10 @@ abstract contract GovernanceTokenBase is ERC20Upgradeable, IGovernanceToken {
//}

function _unwrap(address from, address to, uint amount) internal virtual {
tokenExternal.transfer(to, amount);
require(
tokenExternal.transfer(to, amount),
"GovernanceToken: transfer failed"
);
super._burn(from, amount);
}

Expand Down
3 changes: 1 addition & 2 deletions contracts/GovernanceToken/GovernanceTokenSnapshot.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;
pragma solidity 0.8.16;

import "@openzeppelin/contracts/utils/Arrays.sol";
import "./IGovernanceToken.sol";
Expand Down
3 changes: 1 addition & 2 deletions contracts/GovernanceToken/IGovernanceToken.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;
pragma solidity 0.8.16;

import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import "../extensions/ISnapshot.sol";
Expand Down
14 changes: 9 additions & 5 deletions contracts/InternalMarket/InternalMarket.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;
pragma solidity 0.8.16;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
Expand All @@ -23,13 +22,18 @@ contract InternalMarket is Initializable, HasRole, InternalMarketBase {
/**
* @dev Initializes the contract with the given roles and internal token.
* @param roles DAORoles instance containing custom access control roles.
* @param tokenInternal_ Reference to governance token.
* @param governanceToken Reference to governance token.
*/
function initialize(
DAORoles roles,
IGovernanceToken tokenInternal_
IGovernanceToken governanceToken
) public initializer {
_initialize(tokenInternal_, 7 days);
require(
address(roles) != address(0) &&
address(governanceToken) != address(0),
"InternalMarket: 0x0 not allowed"
);
_initialize(governanceToken, 7 days);
_setRoles(roles);
}

Expand Down
6 changes: 4 additions & 2 deletions contracts/InternalMarket/InternalMarketBase.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;
pragma solidity 0.8.16;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "../ShareholderRegistry/IShareholderRegistry.sol";
Expand All @@ -18,6 +17,7 @@ contract InternalMarketBase {
);

event OfferMatched(uint128 id, address from, address to, uint256 amount);
event Withdrawn(address from, address to, uint256 amount);

struct Offer {
uint256 expiredAt;
Expand Down Expand Up @@ -204,6 +204,8 @@ contract InternalMarketBase {
} else {
tokenInternal.unwrap(from, to, amount);
}

emit Withdrawn(from, to, amount);
}

function _burn(address from, uint256 amount) internal virtual {
Expand Down
3 changes: 1 addition & 2 deletions contracts/NeokingdomToken/INeokingdomToken.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;
pragma solidity 0.8.16;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

Expand Down
2 changes: 1 addition & 1 deletion contracts/NeokingdomToken/NeokingdomToken.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
pragma solidity 0.8.16;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
Expand Down
3 changes: 1 addition & 2 deletions contracts/RedemptionController/IRedemptionController.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;
pragma solidity 0.8.16;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol";
Expand Down
7 changes: 5 additions & 2 deletions contracts/RedemptionController/RedemptionController.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.16;
pragma solidity 0.8.16;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "./RedemptionControllerBase.sol";
Expand Down Expand Up @@ -36,6 +35,10 @@ contract RedemptionController is
* @param roles The addresses of DAORoles for this contract.
*/
function initialize(DAORoles roles) public initializer {
require(
address(roles) != address(0),
"RedemptionController: 0x0 not allowed"
);
_setRoles(roles);
_initialize();
}
Expand Down
57 changes: 48 additions & 9 deletions contracts/RedemptionController/RedemptionControllerBase.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
pragma solidity 0.8.16;

import "./IRedemptionController.sol";
import "hardhat/console.sol";

// The contract tells how many tokens are redeemable by Contributors
abstract contract RedemptionControllerBase is IRedemptionController {
Expand Down Expand Up @@ -29,6 +30,21 @@ abstract contract RedemptionControllerBase is IRedemptionController {
mapping(address => MintBudget[]) internal _mintBudgets;
mapping(address => uint256) internal _mintBudgetsStartIndex;

event RedemptionCreated(
address account,
uint256 index,
uint256 amount,
uint256 starts,
uint256 ends
);

event RedemptionUpdated(
address from,
uint256 index,
uint256 amountRequested,
uint256 amountRedeemed
);

function _initialize() internal {
redemptionStart = 60 days;
redemptionWindow = 10 days;
Expand Down Expand Up @@ -69,7 +85,7 @@ abstract contract RedemptionControllerBase is IRedemptionController {
}

function _afterOffer(address account, uint256 amount) internal virtual {
// Find tokens minted ofer the last 3 months of activity, no earlier than 15 months
// Find tokens minted over the last 3 months of activity, no earlier than 15 months
if (_mintBudgets[account].length == 0) {
return;
}
Expand Down Expand Up @@ -192,28 +208,44 @@ abstract contract RedemptionControllerBase is IRedemptionController {
}
}

function _afterRedeem(address account, uint256 amount) internal virtual {
function _afterRedeem(
address account,
uint256 amountRequested
) internal virtual {
Redeemable[] storage redeemables = _redeemables[account];
uint256 amountLeft = amountRequested;

for (uint256 i = 0; i < redeemables.length && amount > 0; i++) {
for (uint256 i = 0; i < redeemables.length && amountLeft > 0; i++) {
Redeemable storage redeemable = redeemables[i];
if (
block.timestamp >= redeemable.start &&
block.timestamp < redeemable.end
) {
if (amount < redeemable.amount) {
redeemable.amount -= amount;
amount = 0;
if (amountLeft < redeemable.amount) {
redeemable.amount -= amountLeft;
emit RedemptionUpdated(
account,
i,
amountRequested,
amountLeft
);
amountLeft = 0;
} else {
amount -= redeemable.amount;
amountLeft -= redeemable.amount;
emit RedemptionUpdated(
account,
i,
amountRequested,
redeemable.amount
);
redeemable.amount = 0;
// FIXME: delete object from array?
}
}
}

require(
amount == 0,
amountLeft == 0,
"Redemption controller: amount exceeds redeemable balance"
);
}
Expand All @@ -232,6 +264,13 @@ abstract contract RedemptionControllerBase is IRedemptionController {
redemptionStarts,
redemptionStarts + redemptionWindow
);
emit RedemptionCreated(
account,
_redeemables[account].length,
amount,
offerRedeemable.start,
offerRedeemable.end
);
_redeemables[account].push(offerRedeemable);
}
}
30 changes: 8 additions & 22 deletions contracts/ResolutionManager/ResolutionManager.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
pragma solidity 0.8.16;

import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import { Roles } from "../extensions/Roles.sol";
Expand All @@ -26,6 +26,13 @@ contract ResolutionManager is Initializable, ResolutionManagerBase, HasRole {
IGovernanceToken governanceToken,
IVoting voting
) public initializer {
require(
address(roles) != address(0) &&
address(shareholderRegistry) != address(0) &&
address(governanceToken) != address(0) &&
address(voting) != address(0),
"ResolutionManager: 0x0 not allowed"
);
_setRoles(roles);
_initialize(shareholderRegistry, governanceToken, voting);
}
Expand Down Expand Up @@ -167,13 +174,6 @@ contract ResolutionManager is Initializable, ResolutionManagerBase, HasRole {
* @param resolutionId The id of the resolution to approve.
*/
function approveResolution(uint256 resolutionId) external virtual {
require(
_shareholderRegistry.isAtLeast(
_shareholderRegistry.MANAGING_BOARD_STATUS(),
_msgSender()
),
"Resolution: only managing board can approve"
);
_approveResolution(resolutionId);
}

Expand All @@ -182,13 +182,6 @@ contract ResolutionManager is Initializable, ResolutionManagerBase, HasRole {
* @param resolutionId The id of the resolution to reject.
*/
function rejectResolution(uint256 resolutionId) external virtual {
require(
_shareholderRegistry.isAtLeast(
_shareholderRegistry.MANAGING_BOARD_STATUS(),
_msgSender()
),
"Resolution: only managing board can reject"
);
_rejectResolution(resolutionId);
}

Expand All @@ -209,13 +202,6 @@ contract ResolutionManager is Initializable, ResolutionManagerBase, HasRole {
address[] memory executionTo,
bytes[] memory executionData
) external virtual {
require(
_shareholderRegistry.isAtLeast(
_shareholderRegistry.MANAGING_BOARD_STATUS(),
_msgSender()
),
"Resolution: only managing board can update"
);
_updateResolution(
resolutionId,
dataURI,
Expand Down
Loading

0 comments on commit ce80a89

Please sign in to comment.