Welcome to stackOverflow - An awesome platform for developers 
If you stick around, you will also find it very rewarding. 
Now to your question.
* is a special character for sed when it is included in pattern to match. More info here.
Thus, we need to escape it with a \.
You can use something like old=$(echo "${old}" | sed -r 's/[*]/\\*/g') to do so for each * inside variable old.
- echo "${old}" |feeds the value of variable- oldto- sed.
- Let me write the sedcommand in an expanded form:sed -r's/[*]/\\*/g'
- -rbecause we are using- regexin pattern to match.
- [*]is the- regexand also the pattern to match. Info
- \\*is the replacement string - The first- \is escaping the second- \and- *is being treated as a normal character.
 
- $(  )has been used to assign the final output to variable- old.
Here is the modified script:
#!/bin/bash
# Read the strings
old=`grep "4*4" x`;
new=`grep "4*4" y`;
# Escape * i.e. add \ before it - As * is a special character for sed
old=$(echo "${old}" | sed -r 's/[*]/\\*/g')
# Replace
sed -i "s/${old}/${new}/g" x