-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTokenizedTuitionPayments.sol
More file actions
73 lines (56 loc) · 2.76 KB
/
TokenizedTuitionPayments.sol
File metadata and controls
73 lines (56 loc) · 2.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract TokenizedTuitionPayments is Ownable {
IERC20 public tuitionToken;
struct TuitionPlan {
uint256 totalAmount;
uint256 installmentAmount;
uint256 numberOfInstallments;
uint256 paidInstallments;
uint256 nextPaymentDate;
bool isActive;
}
mapping(address => TuitionPlan) public studentPlans;
event TuitionPlanCreated(address indexed student, uint256 totalAmount, uint256 numberOfInstallments);
event InstallmentPaid(address indexed student, uint256 amount, uint256 remainingInstallments);
event PlanCompleted(address indexed student);
constructor(address _tuitionToken) Ownable(msg.sender) {
tuitionToken = IERC20(_tuitionToken);
}
function createTuitionPlan(address student, uint256 totalAmount, uint256 numberOfInstallments) external onlyOwner {
require(studentPlans[student].isActive == false, "Student already has an active plan");
require(totalAmount > 0 && numberOfInstallments > 0, "Invalid plan parameters");
uint256 installmentAmount = totalAmount / numberOfInstallments;
studentPlans[student] = TuitionPlan({
totalAmount: totalAmount,
installmentAmount: installmentAmount,
numberOfInstallments: numberOfInstallments,
paidInstallments: 0,
nextPaymentDate: block.timestamp + 30 days,
isActive: true
});
emit TuitionPlanCreated(student, totalAmount, numberOfInstallments);
}
function payInstallment() external {
TuitionPlan storage plan = studentPlans[msg.sender];
require(plan.isActive, "No active tuition plan");
require(block.timestamp >= plan.nextPaymentDate, "Too early for next payment");
require(plan.paidInstallments < plan.numberOfInstallments, "All installments paid");
tuitionToken.transferFrom(msg.sender, address(this), plan.installmentAmount);
plan.paidInstallments++;
plan.nextPaymentDate = block.timestamp + 30 days;
emit InstallmentPaid(msg.sender, plan.installmentAmount, plan.numberOfInstallments - plan.paidInstallments);
if (plan.paidInstallments == plan.numberOfInstallments) {
plan.isActive = false;
emit PlanCompleted(msg.sender);
}
}
function getTuitionPlan(address student) external view returns (TuitionPlan memory) {
return studentPlans[student];
}
function withdrawTokens(uint256 amount) external onlyOwner {
tuitionToken.transfer(owner(), amount);
}
}