-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathyul_Operations.sol
176 lines (153 loc) · 5.51 KB
/
yul_Operations.sol
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
// Importing Hardhat's console log to enable debugging during development
import "hardhat/console.sol";
contract YulOperations {
// Function to check if a number is prime using assembly
function isPrime(uint256 x) public pure returns (bool p) {
// Assume the number is prime initially
p = true;
assembly {
// Calculate halfX = x / 2 + 1 to optimize the loop range
let halfX := add(div(x, 2), 1)
// Loop from i = 2 to halfX - 1 (prime checking range)
for {
let i := 2
} lt(i, halfX) {
i := add(i, 1)
} {
// If x is divisible by i (mod(x, i) == 0), it's not a prime number
if iszero(mod(x, i)) {
p := 0 // Set p to false (not prime)
break // Exit the loop early as we found a divisor
}
}
}
}
// Function to add two numbers using assembly
function checkAdd(uint256 a, uint256 b) external pure returns (uint256 c) {
assembly {
// Use the assembly add function to add a and b
c := add(a, b)
}
}
// Function to divide two numbers using assembly
function checkDiv(uint256 a, uint256 b) external pure returns (uint256 c) {
assembly {
// Use the assembly div function to divide a by b
c := div(a, b)
}
}
// Function to check if a is less than b using assembly
function checkLt(uint256 a, uint256 b) external pure returns (uint256 c) {
assembly {
// Use the assembly lt function to check if a < b
c := lt(a, b)
}
}
// Function to calculate the modulus of a and b using assembly
function checkMod(uint256 a, uint256 b) external pure returns (uint256 c) {
assembly {
// Use the assembly mod function to calculate a % b
c := mod(a, b)
}
}
// Function to check if a number is zero using assembly
function checkZero(uint256 a) external pure returns (bool c) {
assembly {
// Use the assembly iszero function to check if a is 0
c := iszero(a)
}
}
// Function to check if a uint256 value is zero using assembly and return bytes32
function checkZeroBytes32(uint256 a) external pure returns (bytes32 c) {
assembly {
// Use the assembly iszero function to check if a is 0 and return a bytes32 result
c := iszero(a)
}
}
// Function that demonstrates a condition where the result is updated based on a truthy value
function isTruthy() external pure returns (uint256 result) {
result = 2; // Initialize result to 2
assembly {
// If the condition (2) is true, set result to 5
if 2 {
result := 5
}
}
return result; // Returns 5 since the condition was true
}
// Function that demonstrates a condition where the result is updated based on a falsy value
function isFalsy() external pure returns (uint256 result) {
result = 1; // Initialize result to 1
assembly {
// If the condition (0) is false, do not update the result
if 0 {
result := 2
}
}
return result; // Returns 1 since the condition was false
}
// Function to demonstrate the use of negation in assembly
function negation() external pure returns (uint256 result) {
result = 1; // Initialize result to 1
assembly {
// Check if 0 is zero (which it is) and update result to 2
if iszero(0) {
result := 2
}
}
return result; // Returns 2 since the condition is true
}
// Function to return the maximum of two values using assembly
function max(uint256 x, uint256 y) external pure returns (uint256 maximum) {
assembly {
// If x is less than y, set maximum to y
if lt(x, y) {
maximum := y
}
// If x is not less than y, set maximum to x
if iszero(lt(x, y)) {
maximum := x
}
}
}
// Function that demonstrates the use of switch-case in assembly for comparing two values
function checkSwitch(uint256 x, uint256 y)
external
pure
returns (uint256 lesser)
{
uint256 sum;
assembly {
// Calculate sum of x and y
sum := add(x, y)
// Switch-case to check which number is lesser and set accordingly
switch lt(x, y)
case true {
// If x is less than y, set lesser to x
lesser := x
}
case false {
// If x is not less than y, set lesser to y
lesser := y
}
}
}
// Function that mimics the behavior of a while loop using a for loop in assembly
function CheckWhile() external pure returns (uint256 result) {
assembly {
// Simulate a while loop using a for loop with i starting at 0
// Condition: while i < 10
// Post-iteration: i = i + 1
for {
let i := 0
} lt(i, 10) {
i := add(i, 1)
} {
// Add the value of i to result in each iteration
result := add(result, i)
}
}
}
}