Skip to content

Commit

Permalink
code clean up and testing
Browse files Browse the repository at this point in the history
  • Loading branch information
newtmex committed Aug 13, 2024
1 parent 4861bd5 commit 1688fee
Show file tree
Hide file tree
Showing 39 changed files with 1,472 additions and 1,449 deletions.
65 changes: 27 additions & 38 deletions packages/backend/contracts/coinbase/Coinbase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,23 @@ pragma solidity 0.8.24;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";

import "../modules/sht-module/SHTModule.sol";
import "../project-funding/ProjectFunding.sol";

/**
* @title Coinbase
* @dev This contract is used to start the ICO for housing projects.
*/
/// @title Coinbase
/// @dev This contract is used to start the ICO for housing projects.
contract Coinbase is Ownable, SHTModule {
using SafeMath for uint256;

constructor() ERC20("SmartHousingToken", "SHT") {
_mint(address(this), SHT.MAX_SUPPLY);
}

/**
* @dev Starts the ICO by initializing the first housing project.
* @param projectFundingAddr Address of the ProjectFunding contract.
* @param smartHousingAddress Address of the SmartHousing contract.
* @param fundingToken Address of the funding token (ERC20).
* @param fundingGoal The funding goal for the new project.
* @param fundingDeadline The deadline for the project funding.
*/
/// @dev Starts the ICO by initializing the first housing project.
/// @param projectFundingAddr Address of the ProjectFunding contract.
/// @param smartHousingAddress Address of the SmartHousing contract.
/// @param fundingToken Address of the funding token (ERC20).
/// @param fundingGoal The funding goal for the new project.
/// @param fundingDeadline The deadline for the project funding.
function startICO(
string memory name,
string memory symbol,
Expand All @@ -35,38 +28,34 @@ contract Coinbase is Ownable, SHTModule {
address fundingToken,
uint256 fundingGoal,
uint256 fundingDeadline
) external onlyOwner {
) external onlyOwner returns (address) {
ERC20TokenPayment memory icoPayment = _makeSHTPayment(SHT.ICO_FUNDS);

// Directly approve the ProjectFunding contract to spend the ICO funds
_approve(address(this), projectFundingAddr, icoPayment.amount);

ProjectFunding(projectFundingAddr).initFirstProject(
icoPayment,
name,
symbol,
smartHousingAddress,
fundingToken,
fundingGoal,
fundingDeadline
);
return
ProjectFunding(projectFundingAddr).initFirstProject(
icoPayment,
name,
symbol,
smartHousingAddress,
fundingToken,
fundingGoal,
fundingDeadline
);
}

/**
* @dev Dispatches ecosystem funds if not already dispatched to SmartHousing contract.
* @param smartHousingAddr The address of the SmartHousing contract.
*/
/// @dev Dispatches ecosystem funds if not already dispatched to SmartHousing contract.
/// @param smartHousingAddr The address of the SmartHousing contract.
function feedSmartHousing(address smartHousingAddr) external onlyOwner {
ERC20TokenPayment memory feedPayment = _makeSHTPayment(
SHT.ECOSYSTEM_DISTRIBUTION_FUNDS
);
uint256 feedAmount = SHT.ECOSYSTEM_DISTRIBUTION_FUNDS;
require(balanceOf(address(this)) >= feedAmount, "Already dispatched");

// Ensure data integrity
require(
balanceOf(address(this)) >= feedPayment.amount,
"Already dispatched"
);
ERC20TokenPayment memory feedPayment = _makeSHTPayment(feedAmount);

_approve(address(this), smartHousingAddr, feedPayment.amount);
// Directly approve the SmartHousing contract to spend the ecosystem funds
_approve(address(this), smartHousingAddr, feedAmount);

ISmartHousing(smartHousingAddr).setUpSHT(feedPayment);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import "../main/Interface.sol";

abstract contract CallsSmartHousing {
/// @notice The address of the main SmartHousing contract.
address immutable smartHousingAddr;
address public immutable smartHousingAddr;

constructor(address smartHousingAddr_) {
smartHousingAddr = smartHousingAddr_;
Expand All @@ -14,9 +14,9 @@ abstract contract CallsSmartHousing {
/// @dev Gets the referrer address for a given original owner.
/// @param userAddr The original owner of the token.
/// @return The referrer address.
function getReferrer(
function _getReferrer(
address userAddr
) internal view returns (uint, address) {
) internal view returns (uint256, address) {
return IUserModule(smartHousingAddr).getReferrer(userAddr);
}
}
131 changes: 116 additions & 15 deletions packages/backend/contracts/housing-project/HousingProject.sol
Original file line number Diff line number Diff line change
@@ -1,40 +1,141 @@
// SPDX-License-Identifier: SEE LICENSE IN LICENSE
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import "@openzeppelin/contracts/access/Ownable.sol";
import "./RentsModule.sol";
import "./CallsSmartHousing.sol";

/// @title HousingProject Contract
/// @notice Represents a unique real estate project within the SmartHousing ecosystem.
/// @dev This contract inherits from RentsModule and HousingSFT.
contract HousingProject is RentsModule, Ownable {
/// @dev This contract inherits from RentsModule and Ownable for management functions.
contract HousingProject is RentsModule, Ownable, CallsSmartHousing {
using RewardShares for rewardshares;
using TokenPayments for ERC20TokenPayment;

// State Variables
uint256 public rewardsReserve;
uint256 public facilityManagementFunds;

// Constants
uint256 public constant REWARD_PERCENT = 75;
uint256 public constant ECOSYSTEM_PERCENT = 18;
uint256 public constant FACILITY_PERCENT = 7;

HousingSFT public immutable projectSFT;
ERC20Burnable public immutable housingToken;

/// @notice Initializes the HousingProject contract.
/// @param smartHousingAddr The address of the main SmartHousing contract.
/// @param housingTokenAddr Coinbase contraact address
/// @param name The name of the HousingSFT token.
/// @param symbol The symbol of the HousingSFT token.
constructor(
string memory name,
string memory symbol,
address smartHousingAddr
address smartHousingAddr,
address housingTokenAddr
) CallsSmartHousing(smartHousingAddr) {
projectSFT = new HousingSFT(name, symbol);

// Initialize the housing token
housingToken = ERC20Burnable(housingTokenAddr);
}

event TokenIssued(address tokenAddress, string name, uint256 amountRaised);
/// @notice Receives rent payments, calculates, and distributes rewards.
/// @param rentPayment The details of the rent payment.
function receiveRent(ERC20TokenPayment calldata rentPayment) external {
uint256 rentAmount = rentPayment.amount;
require(rentAmount > 0, "RentsModule: Insufficient amount");
require(
rentPayment.token == housingToken,
"RentsModule: Invalid token"
);

function setTokenDetails(
uint256 amountRaised,
address housingTokenAddr
) external onlyOwner {
require(address(housingToken) == address(0), "Token details set already");
rentPayment.receiveERC20();

housingToken = ERC20Burnable(housingTokenAddr);
uint256 rentReward = (rentAmount * REWARD_PERCENT) / 100;
uint256 ecosystemReward = (rentAmount * ECOSYSTEM_PERCENT) / 100;
uint256 facilityReward = (rentAmount * FACILITY_PERCENT) / 100;

projectSFT.setAmountRaised(amountRaised);
string memory name = projectSFT.name();
// Update rewards and reserve
rewardPerShare +=
(rentReward * DIVISION_SAFETY_CONST) /
projectSFT.getMaxSupply();
rewardsReserve += rentReward;
facilityManagementFunds += facilityReward;

emit TokenIssued(address(projectSFT), name, amountRaised);
// Burn ecosystem reward and notify SmartHousing contract
housingToken.burn(ecosystemReward);
ISmartHousing(smartHousingAddr).addProjectRent(rentAmount);
}

function getMaxSupply() public view returns (uint256) {
/// @notice Claims rent rewards for a given token and updates attributes.
/// @param nonce The nonce of the token to claim rewards for.
/// @return attr The updated HousingAttributes.
/// @return rewardShares The computed reward shares.
/// @return newNonce The new nonce after updating the token.
function claimRentReward(
uint256 nonce
)
external
returns (
HousingAttributes memory attr,
rewardshares memory rewardShares,
uint256 newNonce
)
{
address caller = msg.sender;
uint256 currentRPS = rewardPerShare;

attr = projectSFT.getUserSFT(caller, nonce);
rewardShares = _computeRewardShares(attr);

uint256 totalReward = rewardShares.total();
if (totalReward == 0) {
return (attr, rewardShares, nonce);
}

require(
rewardsReserve >= totalReward,
"RentsModule: Insufficient rewards reserve"
);
rewardsReserve -= totalReward;

(, address referrer) = _getReferrer(attr.originalOwner);
if (rewardShares.referrerValue > 0) {
if (referrer != address(0)) {
housingToken.transfer(referrer, rewardShares.referrerValue);
} else {
housingToken.burn(rewardShares.referrerValue);
}
}

attr.rewardsPerShare = currentRPS;

newNonce = projectSFT.update(
caller,
nonce,
projectSFT.balanceOf(caller, nonce),
abi.encode(attr)
);

housingToken.transfer(caller, rewardShares.userValue);

return (attr, rewardShares, newNonce);
}

/// @notice Returns the maximum supply of the HousingSFT token.
/// @return The maximum supply of the HousingSFT token.
function getMaxSupply() external view returns (uint256) {
return projectSFT.getMaxSupply();
}

/// @notice Calculates the amount of rent claimable for a given token.
/// @param attr The attributes of the token.
/// @return The amount of rent claimable.
function rentClaimable(
HousingAttributes memory attr
) public view returns (uint256) {
return _computeRewardShares(attr).userValue;
}
}
Loading

0 comments on commit 1688fee

Please sign in to comment.